/* ** 2007 August 14 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement mutexes for Win32. */ #include "sqliteInt.h" #if SQLITE_OS_WIN /* ** Include code that is common to all os_*.c files */ #include "os_common.h" /* ** Include the header file for the Windows VFS. */ #include "os_win.h" #endif /* ** The code in this file is only used if we are compiling multithreaded ** on a Win32 system. */ #ifdef SQLITE_MUTEX_W32 #if MSVC_VERSION>0 # define ALIGN128 __declspec(align(128)) #else # define ALIGN128 #endif #pragma warning(push) #pragma warning(disable: 4324) /* ** Each SQLite mutex is an instance of the following structure. ** ** The ALIGN128 macro attempts to force 128-byte alignment on mutexes, ** so that adjacent mutex objects are always on different cache lines ** in the CPU. This is CPU-dependent, of course, but 128-byte alignment ** seems to work well for all contemporary processors. Experiments show ** that 64 works just as well most of the time, but the internet says ** that 128-byte alignment works better. */ struct sqlite3_mutex { union { CRITICAL_SECTION cs; /* The CRITICAL_SECTION mutex. id==1 */ SRWLOCK srwl; /* The Slim reader/writer lock. id!=1 */ } u; int id; /* Mutex type */ #ifdef SQLITE_DEBUG volatile int nRef; /* Number of entrances */ volatile DWORD owner; /* Thread holding this mutex */ volatile LONG trace; /* True to trace changes */ #endif }; #pragma warning(pop) #ifdef SQLITE_DEBUG /* ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are ** intended for use only inside assert() statements. */ static int winMutexHeld(sqlite3_mutex *p){ return p->nRef!=0 && p->owner==GetCurrentThreadId(); } static int winMutexNotheld(sqlite3_mutex *p){ return p->nRef==0 || p->owner!=GetCurrentThreadId(); } #endif /* ** Try to provide a memory barrier operation, needed for initialization ** and also for the xShmBarrier method of the VFS in cases when SQLite is ** compiled without mutexes (SQLITE_THREADSAFE=0). */ void sqlite3MemoryBarrier(void){ #if defined(SQLITE_MEMORY_BARRIER) SQLITE_MEMORY_BARRIER; #elif defined(__GNUC__) __sync_synchronize(); #elif MSVC_VERSION>=1400 _ReadWriteBarrier(); #elif defined(MemoryBarrier) MemoryBarrier(); #endif } /* ** Static mutexes. ** ** The ALIGN128 macro on the static mutex array forces 128-byte alignment ** on the mutexes so that adjacent mutex objects are always on different ** cache lines in the CPU. This is CPU-dependent, of course, but 128-byte ** alignment seems to work well for all contemporary processors. ** Experiments show that 64 works just as well most of the time, but ** the internet says that 128-byte alignment works better. */ static ALIGN128 union staticMutexes { sqlite3_mutex m; char spacer[128]; } aWindowsMutex[12]; static int winMutex_isInit = 0; /* As the winMutexInit() and winMutexEnd() functions are called as part ** of the sqlite3_initialize() and sqlite3_shutdown() processing, the ** "interlocked" magic used here is probably not strictly necessary. */ static LONG volatile winMutex_lock = 0; void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ static int winMutexInit(void){ /* The first to increment to 1 does actual initialization */ if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ int i; for(i=0; iid = i+2; InitializeSRWLock(&p->u.srwl); #ifdef SQLITE_DEBUG p->nRef = 0; p->owner = 0; p->trace = 0; #endif } winMutex_isInit = 1; }else{ /* Another thread is (in the process of) initializing the static ** mutexes */ while( !winMutex_isInit ){ sqlite3_win32_sleep(1); } } return SQLITE_OK; } static int winMutexEnd(void){ /* The first to decrement to 0 does actual shutdown ** (which should be the last to shutdown.) */ if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){ if( winMutex_isInit==1 ){ winMutex_isInit = 0; } } return SQLITE_OK; } /* ** The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. If it returns NULL ** that means that a mutex could not be allocated. SQLite ** will unwind its stack and return an error. The argument ** to sqlite3_mutex_alloc() is one of these integer constants: ** ** ** ** The first two constants 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. But 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() each return ** a pointer to a static preexisting mutex. Six 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. But for the static ** mutex types, the same mutex is returned on every call that has ** the same type number. */ static sqlite3_mutex *winMutexAlloc(int iType){ sqlite3_mutex *p; switch( iType ){ case SQLITE_MUTEX_FAST: case SQLITE_MUTEX_RECURSIVE: { p = sqlite3MallocZero( sizeof(*p) ); if( p ){ p->id = iType; #ifdef SQLITE_DEBUG #ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC p->trace = 1; #endif #endif if( iType==SQLITE_MUTEX_RECURSIVE ){ InitializeCriticalSection(&p->u.cs); }else{ InitializeSRWLock(&p->u.srwl); } } break; } default: { #ifdef SQLITE_ENABLE_API_ARMOR if( iType-2<0 || iType-2>=ArraySize(aWindowsMutex) ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif p = &aWindowsMutex[iType-2].m; #ifdef SQLITE_DEBUG #ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC InterlockedCompareExchange(&p->trace, 1, 0); #endif #endif break; } } assert( p==0 || p->id==iType ); return p; } /* ** This routine deallocates a previously ** allocated mutex. SQLite is careful to deallocate every ** mutex that it allocates. */ static void winMutexFree(sqlite3_mutex *p){ assert( p ); assert( p->nRef==0 && p->owner==0 ); if( p->id==SQLITE_MUTEX_FAST ){ sqlite3_free(p); }else if( p->id==SQLITE_MUTEX_RECURSIVE ){ DeleteCriticalSection(&p->u.cs); sqlite3_free(p); }else{ #ifdef SQLITE_ENABLE_API_ARMOR (void)SQLITE_MISUSE_BKPT; #endif } } /* ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt ** to enter a mutex. If another thread is already within the mutex, ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can ** be entered multiple times by the same thread. In such cases the, ** mutex must be exited an equal number of times before another thread ** can enter. If the same thread tries to enter any other kind of mutex ** more than once, the behavior is undefined. */ static void winMutexEnter(sqlite3_mutex *p){ assert( p ); #ifdef SQLITE_DEBUG assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) ); #endif assert( winMutex_isInit==1 ); if( p->id==SQLITE_MUTEX_RECURSIVE ){ EnterCriticalSection(&p->u.cs); }else{ AcquireSRWLockExclusive(&p->u.srwl); } #ifdef SQLITE_DEBUG assert( p->nRef>0 || p->owner==0 ); p->owner = GetCurrentThreadId(); p->nRef++; if( p->trace ){ OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n", GetCurrentThreadId(), p->id, p, p->trace, p->nRef)); } #endif } static int winMutexTry(sqlite3_mutex *p){ int rc = SQLITE_BUSY; assert( p ); assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) ); /* ** The sqlite3_mutex_try() routine is seldom used, and when it is ** used it is merely an optimization. So it is OK for it to always ** fail. */ if( p->id==SQLITE_MUTEX_RECURSIVE ){ rc = TryEnterCriticalSection(&p->u.cs); }else{ rc = TryAcquireSRWLockExclusive(&p->u.srwl); } if( rc ){ #ifdef SQLITE_DEBUG p->owner = GetCurrentThreadId(); p->nRef++; #endif rc = SQLITE_OK; }else{ rc = SQLITE_BUSY; } #ifdef SQLITE_DEBUG if( p->trace ){ OSTRACE(( "TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n", GetCurrentThreadId(), p->id, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc))); } #endif return rc; } /* ** The sqlite3_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior ** is undefined if the mutex is not currently entered or ** is not currently allocated. SQLite will never do either. */ static void winMutexLeave(sqlite3_mutex *p){ assert( p ); #ifdef SQLITE_DEBUG assert( p->nRef>0 ); assert( p->owner==GetCurrentThreadId() ); p->nRef--; if( p->nRef==0 ) p->owner = 0; assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); #endif assert( winMutex_isInit==1 ); if( p->id==SQLITE_MUTEX_RECURSIVE ){ LeaveCriticalSection(&p->u.cs); }else{ ReleaseSRWLockExclusive(&p->u.srwl); } #ifdef SQLITE_DEBUG if( p->trace ){ OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n", GetCurrentThreadId(), p->id, p, p->trace, p->nRef)); } #endif } sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ static const sqlite3_mutex_methods sMutex = { winMutexInit, winMutexEnd, winMutexAlloc, winMutexFree, winMutexEnter, winMutexTry, winMutexLeave, #ifdef SQLITE_DEBUG winMutexHeld, winMutexNotheld #else 0, 0 #endif }; return &sMutex; } #endif /* SQLITE_MUTEX_W32 */