SQLite

Changes On Branch mutexInitCmpSwap
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch mutexInitCmpSwap Excluding Merge-Ins

This is equivalent to a diff from 10a214fd to 6b85f8cd

2015-09-23
19:17
Take care that the number of reserved bits per page is consistent between the source and destination databases when doing the back-copy on a VACUUM. (check-in: 5b61b72f user: drh tags: trunk)
16:35
Merge updates from trunk. (check-in: 0a75ebd2 user: mistachkin tags: mutexInitIsInitReCheck)
16:24
Simplify thread-safety of mutex initialization. (check-in: da0587c5 user: mistachkin tags: mutexInitSimpleCmpSwap)
15:54
Merge updates from trunk. (Closed-Leaf check-in: 6b85f8cd user: mistachkin tags: mutexInitCmpSwap)
11:59
Capture AFL-generated fuzz tests for json1.c into the test/fuzzdata4.db file. (check-in: 10a214fd user: drh tags: trunk)
01:10
Do not allow a comma at the end of a JSON array or object. (check-in: 7c7a3f3e user: drh tags: trunk)
2015-09-13
18:45
Experimental changes to avoid recusrively calling xMutexInit. (check-in: c9400ff1 user: mistachkin tags: mutexInitCmpSwap)

Changes to src/global.c.

170
171
172
173
174
175
176

177
178
179
180
181
182
183
   SQLITE_USE_URI,            /* bOpenUri */
   SQLITE_ALLOW_COVERING_INDEX_SCAN,   /* bUseCis */
   0x7ffffffe,                /* mxStrlen */
   0,                         /* neverCorrupt */
   128,                       /* szLookaside */
   500,                       /* nLookaside */
   {0,0,0,0,0,0,0,0},         /* m */

   {0,0,0,0,0,0,0,0,0},       /* mutex */
   {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */
   (void*)0,                  /* pHeap */
   0,                         /* nHeap */
   0, 0,                      /* mnHeap, mxHeap */
   SQLITE_DEFAULT_MMAP_SIZE,  /* szMmap */
   SQLITE_MAX_MMAP_SIZE,      /* mxMmap */







>







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
   SQLITE_USE_URI,            /* bOpenUri */
   SQLITE_ALLOW_COVERING_INDEX_SCAN,   /* bUseCis */
   0x7ffffffe,                /* mxStrlen */
   0,                         /* neverCorrupt */
   128,                       /* szLookaside */
   500,                       /* nLookaside */
   {0,0,0,0,0,0,0,0},         /* m */
   (void*)0,                  /* pMutex */
   {0,0,0,0,0,0,0,0,0},       /* mutex */
   {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */
   (void*)0,                  /* pHeap */
   0,                         /* nHeap */
   0, 0,                      /* mnHeap, mxHeap */
   SQLITE_DEFAULT_MMAP_SIZE,  /* szMmap */
   SQLITE_MAX_MMAP_SIZE,      /* mxMmap */

Changes to src/main.c.

167
168
169
170
171
172
173






174
175
176
177
178
179
180
181
  ** This operation is protected by the STATIC_MASTER mutex.  Note that
  ** MutexAlloc() is called for a static mutex prior to initializing the
  ** malloc subsystem - this implies that the allocation of a static
  ** mutex must not require support from the malloc subsystem.
  */
  MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
  sqlite3_mutex_enter(pMaster);






  sqlite3GlobalConfig.isMutexInit = 1;
  if( !sqlite3GlobalConfig.isMallocInit ){
    rc = sqlite3MallocInit();
  }
  if( rc==SQLITE_OK ){
    sqlite3GlobalConfig.isMallocInit = 1;
    if( !sqlite3GlobalConfig.pInitMutex ){
      sqlite3GlobalConfig.pInitMutex =







>
>
>
>
>
>
|







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
  ** This operation is protected by the STATIC_MASTER mutex.  Note that
  ** MutexAlloc() is called for a static mutex prior to initializing the
  ** malloc subsystem - this implies that the allocation of a static
  ** mutex must not require support from the malloc subsystem.
  */
  MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
  sqlite3_mutex_enter(pMaster);
  if( sqlite3GlobalConfig.isInit ){
    assert( sqlite3GlobalConfig.isMutexInit );
    assert( sqlite3GlobalConfig.isMallocInit );
    sqlite3_mutex_leave(pMaster);
    return SQLITE_OK;
  }
  sqlite3GlobalConfig.isMutexInit = 1; /* possibly redundant */
  if( !sqlite3GlobalConfig.isMallocInit ){
    rc = sqlite3MallocInit();
  }
  if( rc==SQLITE_OK ){
    sqlite3GlobalConfig.isMallocInit = 1;
    if( !sqlite3GlobalConfig.pInitMutex ){
      sqlite3GlobalConfig.pInitMutex =
325
326
327
328
329
330
331











332
333
334
335
336
337
338
#endif
  }
  if( sqlite3GlobalConfig.isMutexInit ){
    sqlite3MutexEnd();
    sqlite3GlobalConfig.isMutexInit = 0;
  }












  return SQLITE_OK;
}

/*
** This API allows applications to modify the global configuration of
** the SQLite library at run-time.
**







>
>
>
>
>
>
>
>
>
>
>







331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
#endif
  }
  if( sqlite3GlobalConfig.isMutexInit ){
    sqlite3MutexEnd();
    sqlite3GlobalConfig.isMutexInit = 0;
  }

  /*
  ** Force the state of the mutex subsystem to be completely reset now, even
  ** if the configured xMutexEnd(), if any, failed.  This is not thread-safe.
  ** This is necessary even if the xMutexInit() was never called, due to the
  ** possiblity of this state being changed via SQLITE_CONFIG_MUTEX.  After
  ** this point, the application must enable any custom mutex implementation
  ** again via SQLITE_CONFIG_MUTEX, if necessary.
  */
  sqlite3GlobalConfig.pMutex = 0;
  memset(&sqlite3GlobalConfig.mutex, 0, sizeof(sqlite3_mutex_methods));

  return SQLITE_OK;
}

/*
** This API allows applications to modify the global configuration of
** the SQLite library at run-time.
**
380
381
382
383
384
385
386




387
388



389
390
391
392
393
394
395
      sqlite3GlobalConfig.bCoreMutex = 1;  /* Enable mutex on core */
      sqlite3GlobalConfig.bFullMutex = 1;  /* Enable mutex on connections */
      break;
    }
#endif
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-63666-48755 */
    case SQLITE_CONFIG_MUTEX: {




      /* Specify an alternative mutex implementation */
      sqlite3GlobalConfig.mutex = *va_arg(ap, sqlite3_mutex_methods*);



      break;
    }
#endif
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-14450-37597 */
    case SQLITE_CONFIG_GETMUTEX: {
      /* Retrieve the current mutex implementation */
      *va_arg(ap, sqlite3_mutex_methods*) = sqlite3GlobalConfig.mutex;







>
>
>
>
|
|
>
>
>







397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
      sqlite3GlobalConfig.bCoreMutex = 1;  /* Enable mutex on core */
      sqlite3GlobalConfig.bFullMutex = 1;  /* Enable mutex on connections */
      break;
    }
#endif
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-63666-48755 */
    case SQLITE_CONFIG_MUTEX: {
      /* Atomically compare-and-swap the mutex implementation pointer to
       * help prevent a race condition with sqlite3MutexInit(). */
      if( sqlite3CompareAndSwap((void * volatile *)&sqlite3GlobalConfig.pMutex,
                                0, &sqlite3GlobalConfig.mutex)==0 ){
        /* Specify an alternative mutex implementation */
        sqlite3GlobalConfig.mutex = *va_arg(ap, sqlite3_mutex_methods*);
      }else{
        rc = SQLITE_ERROR;
      }
      break;
    }
#endif
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-14450-37597 */
    case SQLITE_CONFIG_GETMUTEX: {
      /* Retrieve the current mutex implementation */
      *va_arg(ap, sqlite3_mutex_methods*) = sqlite3GlobalConfig.mutex;

Changes to src/mutex.c.

22
23
24
25
26
27
28
29













































30
31
32

33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59

60


61
62
63
64
65
66
67
** allocate a mutex while the system is uninitialized.
*/
static SQLITE_WSD int mutexIsInit = 0;
#endif /* SQLITE_DEBUG && !defined(SQLITE_MUTEX_OMIT) */


#ifndef SQLITE_MUTEX_OMIT
/*













































** Initialize the mutex system.
*/
int sqlite3MutexInit(void){ 

  int rc = SQLITE_OK;

  if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
    /* If the xMutexAlloc method has not been set, then the user did not
    ** install a mutex implementation via sqlite3_config() prior to 
    ** sqlite3_initialize() being called. This block copies pointers to
    ** the default implementation into the sqlite3GlobalConfig structure.
    */
    sqlite3_mutex_methods const *pFrom;
    sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;

    if( sqlite3GlobalConfig.bCoreMutex ){
      pFrom = sqlite3DefaultMutex();
    }else{
      pFrom = sqlite3NoopMutex();
    }
    pTo->xMutexInit = pFrom->xMutexInit;
    pTo->xMutexEnd = pFrom->xMutexEnd;
    pTo->xMutexFree = pFrom->xMutexFree;
    pTo->xMutexEnter = pFrom->xMutexEnter;
    pTo->xMutexTry = pFrom->xMutexTry;
    pTo->xMutexLeave = pFrom->xMutexLeave;
    pTo->xMutexHeld = pFrom->xMutexHeld;
    pTo->xMutexNotheld = pFrom->xMutexNotheld;
    sqlite3MemoryBarrier();
    pTo->xMutexAlloc = pFrom->xMutexAlloc;
  }

  assert( sqlite3GlobalConfig.mutex.xMutexInit );

  rc = sqlite3GlobalConfig.mutex.xMutexInit();



#ifdef SQLITE_DEBUG
  GLOBAL(int, mutexIsInit) = 1;
#endif

  return rc;
}








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>
|
>
|
|
|
|
|


<






|
<
<
<
<
<
<
<

<

>
|
>
|
>
>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94







95

96
97
98
99
100
101
102
103
104
105
106
107
108
109
** allocate a mutex while the system is uninitialized.
*/
static SQLITE_WSD int mutexIsInit = 0;
#endif /* SQLITE_DEBUG && !defined(SQLITE_MUTEX_OMIT) */


#ifndef SQLITE_MUTEX_OMIT
/*
** This structure is for use by mutexIsInvalid() only.  It represents an
** invalid mutex implementation (i.e. one where all the function pointers
** are null).
*/
static const sqlite3_mutex_methods mutexNullMethods = {
  0, /* xMutexInit */
  0, /* xMutexEnd */
  0, /* xMutexAlloc */
  0, /* xMutexFree */
  0, /* xMutexEnter */
  0, /* xMutexTry */
  0, /* xMutexLeave */
  0, /* xMutexHeld */
  0  /* xMutexNotheld */
};

/*
** Returns non-zero if the currently configured mutex implemention is
** invalid (i.e. all of its function pointers are null).
*/
static int mutexIsInvalid(void){
  return memcmp(&sqlite3GlobalConfig.mutex, &mutexNullMethods,
                sizeof(sqlite3_mutex_methods))==0;
}

/*
** Copies a mutex implementation.  Both arguments must point to valid
** memory.
*/
static void mutexCopy(
  sqlite3_mutex_methods *pTo,
  sqlite3_mutex_methods const *pFrom
){
  pTo->xMutexInit = pFrom->xMutexInit;
  pTo->xMutexEnd = pFrom->xMutexEnd;
  pTo->xMutexFree = pFrom->xMutexFree;
  pTo->xMutexEnter = pFrom->xMutexEnter;
  pTo->xMutexTry = pFrom->xMutexTry;
  pTo->xMutexLeave = pFrom->xMutexLeave;
  pTo->xMutexHeld = pFrom->xMutexHeld;
  pTo->xMutexNotheld = pFrom->xMutexNotheld;
  pTo->xMutexAlloc = pFrom->xMutexAlloc;
}

/*
** Initialize the mutex system.
*/
int sqlite3MutexInit(void){ 
  static int initPending = 0;
  int rc;
  if( sqlite3CompareAndSwap((void * volatile *)&sqlite3GlobalConfig.pMutex,
                   0, &sqlite3GlobalConfig.mutex)==0 || mutexIsInvalid() ){
    /* If the mutex implementation pointer has not been set, then the user
    ** did not install a mutex implementation via sqlite3_config() prior to
    ** sqlite3_initialize() being called.  This block copies the pointers
    ** for the default implementation into the sqlite3GlobalConfig structure.
    */
    sqlite3_mutex_methods const *pFrom;


    if( sqlite3GlobalConfig.bCoreMutex ){
      pFrom = sqlite3DefaultMutex();
    }else{
      pFrom = sqlite3NoopMutex();
    }
    mutexCopy(&sqlite3GlobalConfig.mutex, pFrom);







    sqlite3MemoryBarrier();

  }
  if( !initPending ){
    assert( sqlite3GlobalConfig.mutex.xMutexInit );
    initPending = 1;
    rc = sqlite3GlobalConfig.mutex.xMutexInit();
    initPending = 0;
  }

#ifdef SQLITE_DEBUG
  GLOBAL(int, mutexIsInit) = 1;
#endif

  return rc;
}

Changes to src/mutex_noop.c.

24
25
26
27
28
29
30






















31
32
33
34
35
36
37
** If compiled with SQLITE_DEBUG, then additional logic is inserted
** that does error checking on mutexes to make sure they are being
** called correctly.
*/
#include "sqliteInt.h"

#ifndef SQLITE_MUTEX_OMIT























#ifndef SQLITE_DEBUG
/*
** Stub routines for all mutex methods.
**
** This routines provide no mutual exclusion or error checking.
*/







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
** If compiled with SQLITE_DEBUG, then additional logic is inserted
** that does error checking on mutexes to make sure they are being
** called correctly.
*/
#include "sqliteInt.h"

#ifndef SQLITE_MUTEX_OMIT

/*
** Try to provide an atomic compare-and-swap operation on a void pointer,
** needed for initialization only.
*/
void *sqlite3NoopCompareAndSwap(
  void *volatile *pCurVal,
  void *cmpVal,
  void *swapVal
){
  /*
  ** This platform may not have a way to perform an atomic compare-and-swap
  ** operation; therefore, use the fallback algorithm.
  **
  ** WARNING: This code is almost certainly not thread-safe.
  */
  void *oldVal = *pCurVal;
  if( oldVal==cmpVal ){
    *pCurVal = swapVal;
  }
  return oldVal;
}

#ifndef SQLITE_DEBUG
/*
** Stub routines for all mutex methods.
**
** This routines provide no mutual exclusion or error checking.
*/

Changes to src/mutex_unix.c.

86
87
88
89
90
91
92




























93
94
95
96
97
98
99
void sqlite3MemoryBarrier(void){
#if defined(SQLITE_MEMORY_BARRIER)
  SQLITE_MEMORY_BARRIER;
#elif defined(__GNUC__) && GCC_VERSION>=4001000
  __sync_synchronize();
#endif
}





























/*
** Initialize and deinitialize the mutex subsystem.
*/
static int pthreadMutexInit(void){ return SQLITE_OK; }
static int pthreadMutexEnd(void){ return SQLITE_OK; }








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
void sqlite3MemoryBarrier(void){
#if defined(SQLITE_MEMORY_BARRIER)
  SQLITE_MEMORY_BARRIER;
#elif defined(__GNUC__) && GCC_VERSION>=4001000
  __sync_synchronize();
#endif
}

/*
** Try to provide an atomic compare-and-swap operation on a void pointer,
** needed for initialization only.
*/
void *sqlite3CompareAndSwap(
  void *volatile *pCurVal,
  void *cmpVal,
  void *swapVal
){
#if defined(SQLITE_COMPARE_AND_SWAP)
  return SQLITE_COMPARE_AND_SWAP(pCurVal, cmpVal, swapVal);
#elif defined(__GNUC__) && GCC_VERSION>=4001000 && SQLITE_PTRSIZE>4
  return (void *)__sync_val_compare_and_swap_8(
      (u64 volatile *)pCurVal, (u64)cmpVal, (u64)swapVal);
#elif defined(__GNUC__) && GCC_VERSION>=4001000
  return (void *)__sync_val_compare_and_swap_4(
      (u32 volatile *)pCurVal, (u32)cmpVal, (u32)swapVal);
#else
  /*
  ** This platform may not have a way to perform an atomic compare-and-swap
  ** operation; therefore, use the fallback algorithm.
  **
  ** WARNING: This code is almost certainly not thread-safe.
  */
  return sqlite3NoopCompareAndSwap(pCurVal, cmpVal, swapVal);
#endif
}

/*
** Initialize and deinitialize the mutex subsystem.
*/
static int pthreadMutexInit(void){ return SQLITE_OK; }
static int pthreadMutexEnd(void){ return SQLITE_OK; }

Changes to src/mutex_w32.c.

85
86
87
88
89
90
91






















92
93
94
95
96
97
98
  SQLITE_MEMORY_BARRIER;
#elif defined(__GNUC__)
  __sync_synchronize();
#else
  MemoryBarrier();
#endif
}























/*
** Initialize and deinitialize the mutex subsystem.
*/
static sqlite3_mutex winMutex_staticMutexes[] = {
  SQLITE3_MUTEX_INITIALIZER,
  SQLITE3_MUTEX_INITIALIZER,







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
  SQLITE_MEMORY_BARRIER;
#elif defined(__GNUC__)
  __sync_synchronize();
#else
  MemoryBarrier();
#endif
}

/*
** Try to provide an atomic compare-and-swap operation on a void pointer,
** needed for initialization only.
*/
void *sqlite3CompareAndSwap(
  void * volatile *pCurVal,
  void *cmpVal,
  void *swapVal
){
#if defined(SQLITE_COMPARE_AND_SWAP)
  return SQLITE_COMPARE_AND_SWAP(pCurVal, cmpVal, swapVal);
#elif SQLITE_PTRSIZE>4
  return (void *)InterlockedCompareExchange64(
      (LONGLONG SQLITE_WIN32_VOLATILE *)pCurVal, (LONGLONG)swapVal,
      (LONGLONG)cmpVal);
#else
  return (void *)InterlockedCompareExchange(
      (LONG SQLITE_WIN32_VOLATILE *)pCurVal, (LONG)swapVal,
      (LONG)cmpVal);
#endif
}

/*
** Initialize and deinitialize the mutex subsystem.
*/
static sqlite3_mutex winMutex_staticMutexes[] = {
  SQLITE3_MUTEX_INITIALIZER,
  SQLITE3_MUTEX_INITIALIZER,

Changes to src/sqliteInt.h.

2934
2935
2936
2937
2938
2939
2940

2941
2942
2943
2944
2945
2946
2947
  int bOpenUri;                     /* True to interpret filenames as URIs */
  int bUseCis;                      /* Use covering indices for full-scans */
  int mxStrlen;                     /* Maximum string length */
  int neverCorrupt;                 /* Database is always well-formed */
  int szLookaside;                  /* Default lookaside buffer size */
  int nLookaside;                   /* Default lookaside buffer count */
  sqlite3_mem_methods m;            /* Low-level memory allocation interface */

  sqlite3_mutex_methods mutex;      /* Low-level mutex interface */
  sqlite3_pcache_methods2 pcache2;  /* Low-level page-cache interface */
  void *pHeap;                      /* Heap storage space */
  int nHeap;                        /* Size of pHeap[] */
  int mnReq, mxReq;                 /* Min and max heap requests sizes */
  sqlite3_int64 szMmap;             /* mmap() space per open file */
  sqlite3_int64 mxMmap;             /* Maximum value for szMmap */







>







2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
  int bOpenUri;                     /* True to interpret filenames as URIs */
  int bUseCis;                      /* Use covering indices for full-scans */
  int mxStrlen;                     /* Maximum string length */
  int neverCorrupt;                 /* Database is always well-formed */
  int szLookaside;                  /* Default lookaside buffer size */
  int nLookaside;                   /* Default lookaside buffer count */
  sqlite3_mem_methods m;            /* Low-level memory allocation interface */
  sqlite3_mutex_methods *pMutex;    /* Address of mutex member or zero. */
  sqlite3_mutex_methods mutex;      /* Low-level mutex interface */
  sqlite3_pcache_methods2 pcache2;  /* Low-level page-cache interface */
  void *pHeap;                      /* Heap storage space */
  int nHeap;                        /* Size of pHeap[] */
  int mnReq, mxReq;                 /* Min and max heap requests sizes */
  sqlite3_int64 szMmap;             /* mmap() space per open file */
  sqlite3_int64 mxMmap;             /* Maximum value for szMmap */
3185
3186
3187
3188
3189
3190
3191

3192
3193
3194
3195
3196
3197
3198
3199
3200









3201
3202
3203
3204
3205
3206
3207
const sqlite3_mem_methods *sqlite3MemGetMemsys5(void);
#endif


#ifndef SQLITE_MUTEX_OMIT
  sqlite3_mutex_methods const *sqlite3DefaultMutex(void);
  sqlite3_mutex_methods const *sqlite3NoopMutex(void);

  sqlite3_mutex *sqlite3MutexAlloc(int);
  int sqlite3MutexInit(void);
  int sqlite3MutexEnd(void);
#endif
#if !defined(SQLITE_MUTEX_OMIT) && !defined(SQLITE_MUTEX_NOOP)
  void sqlite3MemoryBarrier(void);
#else
# define sqlite3MemoryBarrier()
#endif










sqlite3_int64 sqlite3StatusValue(int);
void sqlite3StatusUp(int, int);
void sqlite3StatusDown(int, int);
void sqlite3StatusSet(int, int);

/* Access to mutexes used by sqlite3_status() */







>









>
>
>
>
>
>
>
>
>







3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
const sqlite3_mem_methods *sqlite3MemGetMemsys5(void);
#endif


#ifndef SQLITE_MUTEX_OMIT
  sqlite3_mutex_methods const *sqlite3DefaultMutex(void);
  sqlite3_mutex_methods const *sqlite3NoopMutex(void);
  void *sqlite3NoopCompareAndSwap(void * volatile *, void *, void *);
  sqlite3_mutex *sqlite3MutexAlloc(int);
  int sqlite3MutexInit(void);
  int sqlite3MutexEnd(void);
#endif
#if !defined(SQLITE_MUTEX_OMIT) && !defined(SQLITE_MUTEX_NOOP)
  void sqlite3MemoryBarrier(void);
#else
# define sqlite3MemoryBarrier()
#endif
#if !defined(SQLITE_MUTEX_OMIT)
# if !defined(SQLITE_MUTEX_NOOP)
   void *sqlite3CompareAndSwap(void * volatile *, void *, void *);
# else
#  define sqlite3CompareAndSwap sqlite3NoopCompareAndSwap
# endif
#else
# define sqlite3CompareAndSwap(x,y,z)
#endif

sqlite3_int64 sqlite3StatusValue(int);
void sqlite3StatusUp(int, int);
void sqlite3StatusDown(int, int);
void sqlite3StatusSet(int, int);

/* Access to mutexes used by sqlite3_status() */