| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- #if defined(SQLITE_MUTEX_RTTHREAD)
- /*
- * rt-thread mutex
- */
- struct sqlite3_mutex {
- struct rt_mutex mutex; /* Mutex controlling the lock */
- int id; /* Mutex type */
- };
- SQLITE_PRIVATE void sqlite3MemoryBarrier(void)
- {
- }
- /*
- ** Initialize and deinitialize the mutex subsystem.
- The argument to sqlite3_mutex_alloc() must one of these integer constants:
- SQLITE_MUTEX_FAST
- SQLITE_MUTEX_RECURSIVE
- SQLITE_MUTEX_STATIC_MASTER
- SQLITE_MUTEX_STATIC_MEM
- SQLITE_MUTEX_STATIC_OPEN
- SQLITE_MUTEX_STATIC_PRNG
- SQLITE_MUTEX_STATIC_LRU
- SQLITE_MUTEX_STATIC_PMEM
- SQLITE_MUTEX_STATIC_APP1
- SQLITE_MUTEX_STATIC_APP2
- SQLITE_MUTEX_STATIC_APP3
- SQLITE_MUTEX_STATIC_VFS1
- SQLITE_MUTEX_STATIC_VFS2
- SQLITE_MUTEX_STATIC_VFS3
- The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
- cause sqlite3_mutex_alloc() to create a new mutex. The new mutex is recursive
- when SQLITE_MUTEX_RECURSIVE is used but not necessarily so when SQLITE_MUTEX_FAST
- is used. The mutex implementation does not need to make a distinction between
- SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does not want to.
- SQLite will only request a recursive mutex in cases where it really needs one.
- If a faster non-recursive mutex implementation is available on the host platform,
- the mutex subsystem might return such a mutex in response to SQLITE_MUTEX_FAST.
- The other allowed parameters to sqlite3_mutex_alloc()
- (anything other than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return
- a pointer to a static preexisting mutex. Nine static mutexes are used by the
- current version of SQLite. Future versions of SQLite may add additional static
- mutexes. Static mutexes are for internal use by SQLite only. Applications that
- use SQLite mutexes should use only the dynamic mutexes returned by SQLITE_MUTEX_FAST
- or SQLITE_MUTEX_RECURSIVE.
- Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST or SQLITE_MUTEX_RECURSIVE)
- is used then sqlite3_mutex_alloc() returns a different mutex on every call.
- For the static mutex types, the same mutex is returned on every call that has the same type number.
- */
- static sqlite3_mutex _static_mutex[12];
- static int _rtthread_mtx_init(void)
- {
- int i;
- rt_err_t err;
- for (i = 0; i < sizeof(_static_mutex) / sizeof(_static_mutex[0]); i++)
- {
- err = rt_mutex_init(&_static_mutex[i].mutex, "sqlmtx", RT_IPC_FLAG_PRIO);
- if (err != RT_EOK)
- {
- return SQLITE_ERROR;
- }
- }
- return SQLITE_OK;
- }
- static int _rtthread_mtx_end(void)
- {
- int i;
- rt_err_t err;
- for (i = 0; i < sizeof(_static_mutex) / sizeof(_static_mutex[0]); i++)
- {
- err = rt_mutex_detach(&_static_mutex[i].mutex);
- _static_mutex[i].mutex.owner = 0;
- _static_mutex[i].mutex.hold = 0;
- if (err != RT_EOK)
- {
- return SQLITE_ERROR;
- }
- }
- return SQLITE_OK;
- }
- static sqlite3_mutex * _rtthread_mtx_alloc(int id)
- {
- sqlite3_mutex *p = NULL;
- switch (id)
- {
- case SQLITE_MUTEX_FAST:
- case SQLITE_MUTEX_RECURSIVE:
- p = sqlite3Malloc(sizeof(sqlite3_mutex));
- if (p != NULL)
- {
- rt_mutex_init(&p->mutex, "sqlmtx", RT_IPC_FLAG_PRIO);
- p->id = id;
- }
- break;
- default:
- assert(id - 2 >= 0);
- assert(id - 2 < ArraySize(_static_mutex) );
- p = &_static_mutex[id - 2];
- p->id = id;
- break;
- }
- return p;
- }
- static void _rtthread_mtx_free(sqlite3_mutex * p)
- {
- assert(p != 0);
- rt_mutex_detach(&p->mutex);
- switch (p->id)
- {
- case SQLITE_MUTEX_FAST:
- case SQLITE_MUTEX_RECURSIVE:
- sqlite3_free(p);
- break;
- default:
- break;
- }
- }
- static void _rtthread_mtx_enter(sqlite3_mutex *p)
- {
- assert(p != 0);
- rt_mutex_take(&p->mutex, RT_WAITING_FOREVER);
- }
- static int _rtthread_mtx_try(sqlite3_mutex *p)
- {
- assert(p != 0);
- if (rt_mutex_take(&p->mutex, RT_WAITING_NO) != RT_EOK)
- {
- return SQLITE_BUSY;
- }
- return SQLITE_OK;
- }
- static void _rtthread_mtx_leave(sqlite3_mutex *p)
- {
- assert(p != 0);
- rt_mutex_release(&p->mutex);
- }
- #ifdef SQLITE_DEBUG
- /*
- If the argument to sqlite3_mutex_held() is a NULL pointer then the routine
- should return 1. This seems counter-intuitive since clearly the mutex cannot
- be held if it does not exist. But the reason the mutex does not exist is
- because the build is not using mutexes. And we do not want the assert()
- containing the call to sqlite3_mutex_held() to fail, so a non-zero return
- is the appropriate thing to do. The sqlite3_mutex_notheld() interface should
- also return 1 when given a NULL pointer.
- */
- static int _rtthread_mtx_held(sqlite3_mutex *p)
- {
- if (p != 0)
- {
- if ((rt_thread_self() == p->mutex.owner) && (p->mutex.hold > 0))
- {
- return 1;
- }
- return 0;
- }
- return 1;
- }
- static int _rtthread_mtx_noheld(sqlite3_mutex *p)
- {
- if (_rtthread_mtx_held(p))
- {
- return 0;
- }
- return 1;
- }
- #endif /* SQLITE_DEBUG */
- SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void)
- {
- static const sqlite3_mutex_methods sMutex = {
- _rtthread_mtx_init,
- _rtthread_mtx_end,
- _rtthread_mtx_alloc,
- _rtthread_mtx_free,
- _rtthread_mtx_enter,
- _rtthread_mtx_try,
- _rtthread_mtx_leave,
- #ifdef SQLITE_DEBUG
- _rtthread_mtx_held,
- _rtthread_mtx_noheld
- #else
- 0,
- 0
- #endif
- };
- return &sMutex;
- }
- #endif /* SQLITE_MUTEX_RTTHREAD */
|