modernc.org/cc@v1.0.1/v2/testdata/_sqlite/src/mutex_unix.c (about)

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