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