mutex_rtthread.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /*
  2. ** 2007 August 28
  3. **
  4. ** The author disclaims copyright to this source code. In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. ** May you do good and not evil.
  8. ** May you find forgiveness for yourself and forgive others.
  9. ** May you share freely, never taking more than you give.
  10. **
  11. *************************************************************************
  12. ** This file contains the C functions that implement mutexes for rtthread
  13. */
  14. #include "sqliteInt.h"
  15. /*
  16. ** The code in this file is only used if we are compiling threadsafe
  17. ** under rt-thread with rt_mutex.
  18. **
  19. ** Note that this implementation requires a version of rt-thread that
  20. ** supports recursive mutexes.
  21. */
  22. #ifdef SQLITE_MUTEX_RTTHREAD
  23. #include <rtthread.h>
  24. /*
  25. ** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields
  26. ** are necessary under two condidtions: (1) Debug builds and (2) using
  27. ** home-grown mutexes. Encapsulate these conditions into a single #define.
  28. */
  29. #if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX)
  30. # define SQLITE_MUTEX_NREF 1
  31. #else
  32. # define SQLITE_MUTEX_NREF 0
  33. #endif
  34. /*
  35. ** Each recursive mutex is an instance of the following structure.
  36. */
  37. struct sqlite3_mutex {
  38. struct rt_mutex mutex; /* Mutex controlling the lock */
  39. #if SQLITE_MUTEX_NREF
  40. int id; /* Mutex type */
  41. volatile int nRef; /* Number of entrances */
  42. volatile rt_thread_t owner; /* Thread that is within this mutex */
  43. int trace; /* True to trace changes */
  44. #endif
  45. };
  46. #define RTT_MUTEX_INITIALIZER { 0 }
  47. #if SQLITE_MUTEX_NREF
  48. #define SQLITE3_MUTEX_INITIALIZER { RTT_MUTEX_INITIALIZER, 0, 0, (rt_thread_t)0, 0 }
  49. #else
  50. #define SQLITE3_MUTEX_INITIALIZER { RTT_MUTEX_INITIALIZER }
  51. #endif
  52. /*
  53. ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
  54. ** intended for use only inside assert() statements. On some platforms,
  55. ** there might be race conditions that can cause these routines to
  56. ** deliver incorrect results. In particular, if rtthread_equal() is
  57. ** not an atomic operation, then these routines might delivery
  58. ** incorrect results. On most platforms, rtthread_equal() is a
  59. ** comparison of two integers and is therefore atomic. But we are
  60. ** told that HPUX is not such a platform. If so, then these routines
  61. ** will not always work correctly on HPUX.
  62. **
  63. ** On those platforms where rtthread_equal() is not atomic, SQLite
  64. ** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to
  65. ** make sure no assert() statements are evaluated and hence these
  66. ** routines are never called.
  67. */
  68. #if !defined(NDEBUG) || defined(SQLITE_DEBUG)
  69. static int rtthreadMutexHeld(sqlite3_mutex *p){
  70. return (p->nRef != 0 && p->owner == rt_thread_self());
  71. }
  72. static int rtthreadMutexNotheld(sqlite3_mutex *p){
  73. return (p->nRef == 0 || p->owner != rt_thread_self());
  74. }
  75. #endif
  76. /*
  77. ** Initialize and deinitialize the mutex subsystem.
  78. */
  79. static int rtthreadMutexInit(void){ return SQLITE_OK; }
  80. static int rtthreadMutexEnd(void){ return SQLITE_OK; }
  81. /*
  82. ** The sqlite3_mutex_alloc() routine allocates a new
  83. ** mutex and returns a pointer to it. If it returns NULL
  84. ** that means that a mutex could not be allocated. SQLite
  85. ** will unwind its stack and return an error. The argument
  86. ** to sqlite3_mutex_alloc() is one of these integer constants:
  87. **
  88. ** <ul>
  89. ** <li> SQLITE_MUTEX_FAST
  90. ** <li> SQLITE_MUTEX_RECURSIVE
  91. ** <li> SQLITE_MUTEX_STATIC_MASTER
  92. ** <li> SQLITE_MUTEX_STATIC_MEM
  93. ** <li> SQLITE_MUTEX_STATIC_MEM2
  94. ** <li> SQLITE_MUTEX_STATIC_PRNG
  95. ** <li> SQLITE_MUTEX_STATIC_LRU
  96. ** <li> SQLITE_MUTEX_STATIC_PMEM
  97. ** </ul>
  98. **
  99. ** The first two constants cause sqlite3_mutex_alloc() to create
  100. ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
  101. ** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
  102. ** The mutex implementation does not need to make a distinction
  103. ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
  104. ** not want to. But SQLite will only request a recursive mutex in
  105. ** cases where it really needs one. If a faster non-recursive mutex
  106. ** implementation is available on the host platform, the mutex subsystem
  107. ** might return such a mutex in response to SQLITE_MUTEX_FAST.
  108. **
  109. ** The other allowed parameters to sqlite3_mutex_alloc() each return
  110. ** a pointer to a static preexisting mutex. Six static mutexes are
  111. ** used by the current version of SQLite. Future versions of SQLite
  112. ** may add additional static mutexes. Static mutexes are for internal
  113. ** use by SQLite only. Applications that use SQLite mutexes should
  114. ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
  115. ** SQLITE_MUTEX_RECURSIVE.
  116. **
  117. ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
  118. ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
  119. ** returns a different mutex on every call. But for the static
  120. ** mutex types, the same mutex is returned on every call that has
  121. ** the same type number.
  122. */
  123. static sqlite3_mutex* rtthreadMutexAlloc(int iType){
  124. static sqlite3_mutex staticMutexes[] = {
  125. SQLITE3_MUTEX_INITIALIZER,
  126. SQLITE3_MUTEX_INITIALIZER,
  127. SQLITE3_MUTEX_INITIALIZER,
  128. SQLITE3_MUTEX_INITIALIZER,
  129. SQLITE3_MUTEX_INITIALIZER,
  130. SQLITE3_MUTEX_INITIALIZER
  131. };
  132. sqlite3_mutex *p;
  133. switch( iType ){
  134. case SQLITE_MUTEX_RECURSIVE: {
  135. p = sqlite3MallocZero( sizeof(*p) );
  136. if( p ){
  137. /* Use a recursive mutex if it is available */
  138. rt_mutex_init(&p->mutex, "sqlmtx", RT_IPC_FLAG_PRIO);
  139. #if SQLITE_MUTEX_NREF
  140. p->id = iType;
  141. #endif
  142. }
  143. break;
  144. }
  145. case SQLITE_MUTEX_FAST: {
  146. p = sqlite3MallocZero( sizeof(*p) );
  147. if( p ){
  148. #if SQLITE_MUTEX_NREF
  149. p->id = iType;
  150. #endif
  151. rt_mutex_init(&p->mutex, "sqlmtx", RT_IPC_FLAG_PRIO);
  152. }
  153. break;
  154. }
  155. default: {
  156. assert( iType-2 >= 0 );
  157. assert( iType-2 < ArraySize(staticMutexes) );
  158. p = &staticMutexes[iType-2];
  159. #if SQLITE_MUTEX_NREF
  160. p->id = iType;
  161. #endif
  162. rt_mutex_init(&p->mutex, "sqlmtx", RT_IPC_FLAG_PRIO);
  163. break;
  164. }
  165. }
  166. return p;
  167. }
  168. /*
  169. ** This routine deallocates a previously
  170. ** allocated mutex. SQLite is careful to deallocate every
  171. ** mutex that it allocates.
  172. */
  173. static void rtthreadMutexFree(sqlite3_mutex *p){
  174. assert( p->nRef==0 );
  175. assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
  176. rt_mutex_detach(&p->mutex);
  177. sqlite3_free(p);
  178. }
  179. /*
  180. ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
  181. ** to enter a mutex. If another thread is already within the mutex,
  182. ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
  183. ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
  184. ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
  185. ** be entered multiple times by the same thread. In such cases the,
  186. ** mutex must be exited an equal number of times before another thread
  187. ** can enter. If the same thread tries to enter any other kind of mutex
  188. ** more than once, the behavior is undefined.
  189. */
  190. static void rtthreadMutexEnter(sqlite3_mutex *p){
  191. assert( p->id==SQLITE_MUTEX_RECURSIVE || rtthreadMutexNotheld(p) );
  192. #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
  193. /* If recursive mutexes are not available, then we have to grow
  194. ** our own. This implementation assumes that rtthread_equal()
  195. ** is atomic - that it cannot be deceived into thinking self
  196. ** and p->owner are equal if p->owner changes between two values
  197. ** that are not equal to self while the comparison is taking place.
  198. ** This implementation also assumes a coherent cache - that
  199. ** separate processes cannot read different values from the same
  200. ** address at the same time. If either of these two conditions
  201. ** are not met, then the mutexes will fail and problems will result.
  202. */
  203. {
  204. rt_thread_t self = rt_thread_self();
  205. if( p->nRef>0 && (p->owner == self) ){
  206. p->nRef++;
  207. }else{
  208. rt_mutex_take(&p->mutex, RT_WAITING_FOREVER);
  209. assert( p->nRef==0 );
  210. p->owner = self;
  211. p->nRef = 1;
  212. }
  213. }
  214. #else
  215. /* Use the built-in recursive mutexes if they are available.
  216. */
  217. rt_mutex_take(&p->mutex, RT_WAITING_FOREVER);
  218. #if SQLITE_MUTEX_NREF
  219. assert( p->nRef>0 || p->owner==0 );
  220. p->owner = rt_thread_self();
  221. p->nRef++;
  222. #endif
  223. #endif
  224. #ifdef SQLITE_DEBUG
  225. if( p->trace ){
  226. rt_kprintf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
  227. }
  228. #endif
  229. }
  230. static int rtthreadMutexTry(sqlite3_mutex *p){
  231. int rc;
  232. assert( p->id==SQLITE_MUTEX_RECURSIVE || rtthreadMutexNotheld(p) );
  233. #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
  234. /* If recursive mutexes are not available, then we have to grow
  235. ** our own. This implementation assumes that rtthread_equal()
  236. ** is atomic - that it cannot be deceived into thinking self
  237. ** and p->owner are equal if p->owner changes between two values
  238. ** that are not equal to self while the comparison is taking place.
  239. ** This implementation also assumes a coherent cache - that
  240. ** separate processes cannot read different values from the same
  241. ** address at the same time. If either of these two conditions
  242. ** are not met, then the mutexes will fail and problems will result.
  243. */
  244. {
  245. rt_thread_t self = rt_thread_self();
  246. if( p->nRef>0 && (p->owner == self) ){
  247. p->nRef++;
  248. rc = SQLITE_OK;
  249. }else if( rt_mutex_take(&p->mutex, RT_WAITING_NO)==RT_EOK ){
  250. assert( p->nRef==0 );
  251. p->owner = self;
  252. p->nRef = 1;
  253. rc = SQLITE_OK;
  254. }else{
  255. rc = SQLITE_BUSY;
  256. }
  257. }
  258. #else
  259. /* Use the built-in recursive mutexes if they are available.
  260. */
  261. if( rt_mutex_take(&p->mutex, RT_WAITING_NO)==RT_EOK ){
  262. #if SQLITE_MUTEX_NREF
  263. p->owner = rt_thread_self();
  264. p->nRef++;
  265. #endif
  266. rc = SQLITE_OK;
  267. }else{
  268. rc = SQLITE_BUSY;
  269. }
  270. #endif
  271. #ifdef SQLITE_DEBUG
  272. if( rc==SQLITE_OK && p->trace ){
  273. rt_kprintf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
  274. }
  275. #endif
  276. return rc;
  277. }
  278. /*
  279. ** The sqlite3_mutex_leave() routine exits a mutex that was
  280. ** previously entered by the same thread. The behavior
  281. ** is undefined if the mutex is not currently entered or
  282. ** is not currently allocated. SQLite will never do either.
  283. */
  284. static void rtthreadMutexLeave(sqlite3_mutex *p){
  285. assert( rtthreadMutexHeld(p) );
  286. #if SQLITE_MUTEX_NREF
  287. p->nRef--;
  288. if( p->nRef==0 ) p->owner = 0;
  289. #endif
  290. assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
  291. #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
  292. if( p->nRef==0 ){
  293. rt_mutex_release(&p->mutex);
  294. }
  295. #else
  296. rt_mutex_release(&p->mutex);
  297. #endif
  298. #ifdef SQLITE_DEBUG
  299. if( p->trace ){
  300. rt_kprintf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
  301. }
  302. #endif
  303. }
  304. sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
  305. static const sqlite3_mutex_methods sMutex = {
  306. rtthreadMutexInit,
  307. rtthreadMutexEnd,
  308. rtthreadMutexAlloc,
  309. rtthreadMutexFree,
  310. rtthreadMutexEnter,
  311. rtthreadMutexTry,
  312. rtthreadMutexLeave,
  313. #ifdef SQLITE_DEBUG
  314. rtthreadMutexHeld,
  315. rtthreadMutexNotheld
  316. #else
  317. 0,
  318. 0
  319. #endif
  320. };
  321. return &sMutex;
  322. }
  323. #endif /* SQLITE_MUTEX_RTTHREAD */