rtthread_mutex.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #if defined(SQLITE_MUTEX_RTTHREAD)
  2. /*
  3. * rt-thread mutex
  4. */
  5. struct sqlite3_mutex {
  6. struct rt_mutex mutex; /* Mutex controlling the lock */
  7. int id; /* Mutex type */
  8. };
  9. SQLITE_PRIVATE void sqlite3MemoryBarrier(void)
  10. {
  11. }
  12. /*
  13. ** Initialize and deinitialize the mutex subsystem.
  14. The argument to sqlite3_mutex_alloc() must one of these integer constants:
  15. SQLITE_MUTEX_FAST
  16. SQLITE_MUTEX_RECURSIVE
  17. SQLITE_MUTEX_STATIC_MASTER
  18. SQLITE_MUTEX_STATIC_MEM
  19. SQLITE_MUTEX_STATIC_OPEN
  20. SQLITE_MUTEX_STATIC_PRNG
  21. SQLITE_MUTEX_STATIC_LRU
  22. SQLITE_MUTEX_STATIC_PMEM
  23. SQLITE_MUTEX_STATIC_APP1
  24. SQLITE_MUTEX_STATIC_APP2
  25. SQLITE_MUTEX_STATIC_APP3
  26. SQLITE_MUTEX_STATIC_VFS1
  27. SQLITE_MUTEX_STATIC_VFS2
  28. SQLITE_MUTEX_STATIC_VFS3
  29. The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
  30. cause sqlite3_mutex_alloc() to create a new mutex. The new mutex is recursive
  31. when SQLITE_MUTEX_RECURSIVE is used but not necessarily so when SQLITE_MUTEX_FAST
  32. is used. The mutex implementation does not need to make a distinction between
  33. SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does not want to.
  34. SQLite will only request a recursive mutex in cases where it really needs one.
  35. If a faster non-recursive mutex implementation is available on the host platform,
  36. the mutex subsystem might return such a mutex in response to SQLITE_MUTEX_FAST.
  37. The other allowed parameters to sqlite3_mutex_alloc()
  38. (anything other than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return
  39. a pointer to a static preexisting mutex. Nine static mutexes are used by the
  40. current version of SQLite. Future versions of SQLite may add additional static
  41. mutexes. Static mutexes are for internal use by SQLite only. Applications that
  42. use SQLite mutexes should use only the dynamic mutexes returned by SQLITE_MUTEX_FAST
  43. or SQLITE_MUTEX_RECURSIVE.
  44. Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST or SQLITE_MUTEX_RECURSIVE)
  45. is used then sqlite3_mutex_alloc() returns a different mutex on every call.
  46. For the static mutex types, the same mutex is returned on every call that has the same type number.
  47. */
  48. static sqlite3_mutex _static_mutex[12];
  49. static int _rtthread_mtx_init(void)
  50. {
  51. int i;
  52. rt_err_t err;
  53. for (i = 0; i < sizeof(_static_mutex) / sizeof(_static_mutex[0]); i++)
  54. {
  55. err = rt_mutex_init(&_static_mutex[i].mutex, "sqlmtx", RT_IPC_FLAG_PRIO);
  56. if (err != RT_EOK)
  57. {
  58. return SQLITE_ERROR;
  59. }
  60. }
  61. return SQLITE_OK;
  62. }
  63. static int _rtthread_mtx_end(void)
  64. {
  65. int i;
  66. rt_err_t err;
  67. for (i = 0; i < sizeof(_static_mutex) / sizeof(_static_mutex[0]); i++)
  68. {
  69. err = rt_mutex_detach(&_static_mutex[i].mutex);
  70. _static_mutex[i].mutex.owner = 0;
  71. _static_mutex[i].mutex.hold = 0;
  72. if (err != RT_EOK)
  73. {
  74. return SQLITE_ERROR;
  75. }
  76. }
  77. return SQLITE_OK;
  78. }
  79. static sqlite3_mutex * _rtthread_mtx_alloc(int id)
  80. {
  81. sqlite3_mutex *p = NULL;
  82. switch (id)
  83. {
  84. case SQLITE_MUTEX_FAST:
  85. case SQLITE_MUTEX_RECURSIVE:
  86. p = sqlite3Malloc(sizeof(sqlite3_mutex));
  87. if (p != NULL)
  88. {
  89. rt_mutex_init(&p->mutex, "sqlmtx", RT_IPC_FLAG_PRIO);
  90. p->id = id;
  91. }
  92. break;
  93. default:
  94. assert(id - 2 >= 0);
  95. assert(id - 2 < ArraySize(_static_mutex) );
  96. p = &_static_mutex[id - 2];
  97. p->id = id;
  98. break;
  99. }
  100. return p;
  101. }
  102. static void _rtthread_mtx_free(sqlite3_mutex * p)
  103. {
  104. assert(p != 0);
  105. rt_mutex_detach(&p->mutex);
  106. switch (p->id)
  107. {
  108. case SQLITE_MUTEX_FAST:
  109. case SQLITE_MUTEX_RECURSIVE:
  110. sqlite3_free(p);
  111. break;
  112. default:
  113. break;
  114. }
  115. }
  116. static void _rtthread_mtx_enter(sqlite3_mutex *p)
  117. {
  118. assert(p != 0);
  119. rt_mutex_take(&p->mutex, RT_WAITING_FOREVER);
  120. }
  121. static int _rtthread_mtx_try(sqlite3_mutex *p)
  122. {
  123. assert(p != 0);
  124. if (rt_mutex_take(&p->mutex, RT_WAITING_NO) != RT_EOK)
  125. {
  126. return SQLITE_BUSY;
  127. }
  128. return SQLITE_OK;
  129. }
  130. static void _rtthread_mtx_leave(sqlite3_mutex *p)
  131. {
  132. assert(p != 0);
  133. rt_mutex_release(&p->mutex);
  134. }
  135. #ifdef SQLITE_DEBUG
  136. /*
  137. If the argument to sqlite3_mutex_held() is a NULL pointer then the routine
  138. should return 1. This seems counter-intuitive since clearly the mutex cannot
  139. be held if it does not exist. But the reason the mutex does not exist is
  140. because the build is not using mutexes. And we do not want the assert()
  141. containing the call to sqlite3_mutex_held() to fail, so a non-zero return
  142. is the appropriate thing to do. The sqlite3_mutex_notheld() interface should
  143. also return 1 when given a NULL pointer.
  144. */
  145. static int _rtthread_mtx_held(sqlite3_mutex *p)
  146. {
  147. if (p != 0)
  148. {
  149. if ((rt_thread_self() == p->mutex.owner) && (p->mutex.hold > 0))
  150. {
  151. return 1;
  152. }
  153. return 0;
  154. }
  155. return 1;
  156. }
  157. static int _rtthread_mtx_noheld(sqlite3_mutex *p)
  158. {
  159. if (_rtthread_mtx_held(p))
  160. {
  161. return 0;
  162. }
  163. return 1;
  164. }
  165. #endif /* SQLITE_DEBUG */
  166. SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void)
  167. {
  168. static const sqlite3_mutex_methods sMutex = {
  169. _rtthread_mtx_init,
  170. _rtthread_mtx_end,
  171. _rtthread_mtx_alloc,
  172. _rtthread_mtx_free,
  173. _rtthread_mtx_enter,
  174. _rtthread_mtx_try,
  175. _rtthread_mtx_leave,
  176. #ifdef SQLITE_DEBUG
  177. _rtthread_mtx_held,
  178. _rtthread_mtx_noheld
  179. #else
  180. 0,
  181. 0
  182. #endif
  183. };
  184. return &sMutex;
  185. }
  186. #endif /* SQLITE_MUTEX_RTTHREAD */