/ Check-in [160593dc]
Login

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

Overview
Comment:Change the design of the mutex interface to allow for both "fast" and "recursive" mutexes. (CVS 4238)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 160593dcc5690af715b775c81137c6e09cca6454
User & Date: drh 2007-08-16 19:40:17
Context
2007-08-17
01:14
Begin adding mutexes. Compiles without SQLITE_OMIT_SHARED_CACHE but we get an assertion fault on the shared cache testing. (CVS 4239) check-in: 4c1e9ffe user: drh tags: trunk
2007-08-16
19:40
Change the design of the mutex interface to allow for both "fast" and "recursive" mutexes. (CVS 4238) check-in: 160593dc user: drh tags: trunk
13:01
Remove the thread specific data subsystem from the unix build. Remove legacy cruft from sqliteInt.h. Use the new mutex subsystem in the PRNG. (CVS 4237) check-in: 3d60c14a user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/mem1.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
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
...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133



134
135
136





137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
...
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
**    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 a memory
** allocation subsystem for use by SQLite.  
**
** $Id: mem1.c,v 1.4 2007/08/16 13:01:45 drh Exp $
*/

/*
** This version of the memory allocator is the default.  It is
** used when no other memory allocator is specified using compile-time
** macros.
*/
................................................................................

/*
** Return the amount of memory currently checked out.
*/
sqlite3_uint64 sqlite3_memory_used(void){
  sqlite3_uint64 n;
  if( mem.mutex==0 ){
    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_MEM);
  }
  sqlite3_mutex_enter(mem.mutex, 1);
  n = mem.nowUsed;
  sqlite3_mutex_leave(mem.mutex);  
  return n;
}

/*
** Return the maximum amount of memory that has ever been
** checked out since either the beginning of this process
** or since the most recent reset.
*/
sqlite3_uint64 sqlite3_memory_highwater(int resetFlag){
  sqlite3_uint64 n;
  if( mem.mutex==0 ){
    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_MEM);
  }
  sqlite3_mutex_enter(mem.mutex, 1);
  n = mem.mxUsed;
  if( resetFlag ){
    mem.mxUsed = mem.nowUsed;
  }
  sqlite3_mutex_leave(mem.mutex);  
  return n;
}
................................................................................
*/
int sqlite3_memory_alarm(
  void(*xCallback)(void *pArg, sqlite3_uint64 used, unsigned int N),
  void *pArg,
  sqlite3_uint64 iThreshold
){
  if( mem.mutex==0 ){
    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_MEM);
  }
  sqlite3_mutex_enter(mem.mutex, 1);
  mem.alarmCallback = xCallback;
  mem.alarmArg = pArg;
  mem.alarmThreshold = iThreshold;
  sqlite3_mutex_leave(mem.mutex);
  return SQLITE_OK;
}

/*
** Trigger the alarm 
*/
static void sqlite3MemsysAlarm(unsigned nByte){



  if( mem.alarmCallback==0 || mem.alarmBusy  ) return;
  mem.alarmBusy = 1;
  mem.alarmCallback(mem.alarmArg, mem.nowUsed, nByte);





  mem.alarmBusy = 0;
}

/*
** Allocate nBytes of memory
*/
void *sqlite3_malloc(unsigned int nBytes){
  sqlite3_uint64 *p;
  if( mem.mutex==0 ){
    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_MEM);
  }
  sqlite3_mutex_enter(mem.mutex, 1);
  if( mem.nowUsed+nBytes>=mem.alarmThreshold ){
    sqlite3MemsysAlarm(nBytes);
  }
  p = malloc(nBytes+8);
  if( p==0 ){
    sqlite3MemsysAlarm(nBytes);
    p = malloc(nBytes+8);
................................................................................
  if( pPrior==0 ){
    return;
  }
  assert( mem.mutex!=0 );
  p = pPrior;
  p--;
  nByte = (unsigned int)*p;
  sqlite3_mutex_enter(mem.mutex, 1);
  mem.nowUsed -= nByte;
  free(p);
  sqlite3_mutex_leave(mem.mutex);  
}

/*
** Change the size of an existing memory allocation
................................................................................
    sqlite3_free(pPrior);
    return;
  }
  p = pPrior;
  p--;
  nOld = (unsigned int)p[0];
  assert( mem.mutex!=0 );
  sqlite3_mutex_enter(mem.mutex, 1);
  if( mem.nowUsed+nBytes-nOld>=mem.alarmThreshold ){
    sqlite3MemsysAlarm(nBytes-nOld);
  }
  p = realloc(p, nBytes+8);
  if( p==0 ){
    sqlite3MemsysAlarm(nBytes);
    p = realloc(p, nBytes+8);







|







 







|

|













|

|







 







|

|











>
>
>


|
>
>
>
>
>









|

|







 







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
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
...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
...
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
...
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
**    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 a memory
** allocation subsystem for use by SQLite.  
**
** $Id: mem1.c,v 1.5 2007/08/16 19:40:17 drh Exp $
*/

/*
** This version of the memory allocator is the default.  It is
** used when no other memory allocator is specified using compile-time
** macros.
*/
................................................................................

/*
** Return the amount of memory currently checked out.
*/
sqlite3_uint64 sqlite3_memory_used(void){
  sqlite3_uint64 n;
  if( mem.mutex==0 ){
    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
  }
  sqlite3_mutex_enter(mem.mutex);
  n = mem.nowUsed;
  sqlite3_mutex_leave(mem.mutex);  
  return n;
}

/*
** Return the maximum amount of memory that has ever been
** checked out since either the beginning of this process
** or since the most recent reset.
*/
sqlite3_uint64 sqlite3_memory_highwater(int resetFlag){
  sqlite3_uint64 n;
  if( mem.mutex==0 ){
    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
  }
  sqlite3_mutex_enter(mem.mutex);
  n = mem.mxUsed;
  if( resetFlag ){
    mem.mxUsed = mem.nowUsed;
  }
  sqlite3_mutex_leave(mem.mutex);  
  return n;
}
................................................................................
*/
int sqlite3_memory_alarm(
  void(*xCallback)(void *pArg, sqlite3_uint64 used, unsigned int N),
  void *pArg,
  sqlite3_uint64 iThreshold
){
  if( mem.mutex==0 ){
    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
  }
  sqlite3_mutex_enter(mem.mutex);
  mem.alarmCallback = xCallback;
  mem.alarmArg = pArg;
  mem.alarmThreshold = iThreshold;
  sqlite3_mutex_leave(mem.mutex);
  return SQLITE_OK;
}

/*
** Trigger the alarm 
*/
static void sqlite3MemsysAlarm(unsigned nByte){
  void (*xCallback)(void*,sqlite3_uint64,unsigned);
  sqlite3_uint64 nowUsed;
  void *pArg;
  if( mem.alarmCallback==0 || mem.alarmBusy  ) return;
  mem.alarmBusy = 1;
  xCallback = mem.alarmCallback;
  nowUsed = mem.nowUsed;
  pArg = mem.alarmArg;
  sqlite3_mutex_leave(mem.mutex);
  xCallback(pArg, nowUsed, nByte);
  sqlite3_mutex_enter(mem.mutex);
  mem.alarmBusy = 0;
}

/*
** Allocate nBytes of memory
*/
void *sqlite3_malloc(unsigned int nBytes){
  sqlite3_uint64 *p;
  if( mem.mutex==0 ){
    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
  }
  sqlite3_mutex_enter(mem.mutex);
  if( mem.nowUsed+nBytes>=mem.alarmThreshold ){
    sqlite3MemsysAlarm(nBytes);
  }
  p = malloc(nBytes+8);
  if( p==0 ){
    sqlite3MemsysAlarm(nBytes);
    p = malloc(nBytes+8);
................................................................................
  if( pPrior==0 ){
    return;
  }
  assert( mem.mutex!=0 );
  p = pPrior;
  p--;
  nByte = (unsigned int)*p;
  sqlite3_mutex_enter(mem.mutex);
  mem.nowUsed -= nByte;
  free(p);
  sqlite3_mutex_leave(mem.mutex);  
}

/*
** Change the size of an existing memory allocation
................................................................................
    sqlite3_free(pPrior);
    return;
  }
  p = pPrior;
  p--;
  nOld = (unsigned int)p[0];
  assert( mem.mutex!=0 );
  sqlite3_mutex_enter(mem.mutex);
  if( mem.nowUsed+nBytes-nOld>=mem.alarmThreshold ){
    sqlite3MemsysAlarm(nBytes-nOld);
  }
  p = realloc(p, nBytes+8);
  if( p==0 ){
    sqlite3MemsysAlarm(nBytes);
    p = realloc(p, nBytes+8);

Changes to src/mem2.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
...
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199



200
201
202





203
204
205
206
207
208
209
...
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
...
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
**    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 a memory
** allocation subsystem for use by SQLite.  
**
** $Id: mem2.c,v 1.3 2007/08/15 20:41:29 drh Exp $
*/

/*
** This version of the memory allocator is used only if the
** SQLITE_MEMDEBUG macro is defined and SQLITE_OMIT_MEMORY_ALLOCATION
** is not defined.
*/
................................................................................

/*
** Return the amount of memory currently checked out.
*/
sqlite3_uint64 sqlite3_memory_used(void){
  sqlite3_uint64 n;
  if( mem.mutex==0 ){
    mem.mutex = sqlite3_mutex_alloc(1);
  }
  sqlite3_mutex_enter(mem.mutex, 1);
  n = mem.nowUsed;
  sqlite3_mutex_leave(mem.mutex);  
  return n;
}

/*
** Return the maximum amount of memory that has ever been
** checked out since either the beginning of this process
** or since the most recent reset.
*/
sqlite3_uint64 sqlite3_memory_highwater(int resetFlag){
  sqlite3_uint64 n;
  if( mem.mutex==0 ){
    mem.mutex = sqlite3_mutex_alloc(1);
  }
  sqlite3_mutex_enter(mem.mutex, 1);
  n = mem.mxUsed;
  if( resetFlag ){
    mem.mxUsed = mem.nowUsed;
  }
  sqlite3_mutex_leave(mem.mutex);  
  return n;
}
................................................................................
*/
int sqlite3_memory_alarm(
  void(*xCallback)(void *pArg, sqlite3_uint64 used, unsigned int N),
  void *pArg,
  sqlite3_uint64 iThreshold
){
  if( mem.mutex==0 ){
    mem.mutex = sqlite3_mutex_alloc(1);
  }
  sqlite3_mutex_enter(mem.mutex, 1);
  mem.alarmCallback = xCallback;
  mem.alarmArg = pArg;
  mem.alarmThreshold = iThreshold;
  sqlite3_mutex_leave(mem.mutex);
  return SQLITE_OK;
}

/*
** Trigger the alarm 
*/
static void sqlite3MemsysAlarm(unsigned nByte){



  if( mem.alarmCallback==0 || mem.alarmBusy  ) return;
  mem.alarmBusy = 1;
  mem.alarmCallback(mem.alarmArg, mem.nowUsed, nByte);





  mem.alarmBusy = 0;
}

/*
** Given an allocation, find the MemBlockHdr for that allocation.
**
** This routine checks the guards at either end of the allocation and
................................................................................
  struct MemBlockHdr *pHdr;
  void **pBt;
  unsigned int *pInt;
  void *p;
  unsigned int totalSize;

  if( mem.mutex==0 ){
    mem.mutex = sqlite3_mutex_alloc(1);
  }
  sqlite3_mutex_enter(mem.mutex, 1);
  if( mem.nowUsed+nByte>=mem.alarmThreshold ){
    sqlite3MemsysAlarm(nByte);
  }
  nByte = (nByte+3)&~3;
  totalSize = nByte + sizeof(*pHdr) + sizeof(unsigned int) +
               mem.nBacktrace*sizeof(void*);
  if( mem.iFail>0 ){
................................................................................
  if( pPrior==0 ){
    return;
  }
  assert( mem.mutex!=0 );
  pHdr = sqlite3MemsysGetHeader(pPrior);
  pBt = (void**)pHdr;
  pBt -= pHdr->nBacktraceSlots;
  sqlite3_mutex_enter(mem.mutex, 1);
  mem.nowUsed -= pHdr->iSize;
  if( pHdr->pPrev ){
    assert( pHdr->pPrev->pNext==pHdr );
    pHdr->pPrev->pNext = pHdr->pNext;
  }else{
    assert( mem.pFirst==pHdr );
    mem.pFirst = pHdr->pNext;







|







 







|

|













|

|







 







|

|











>
>
>


|
>
>
>
>
>







 







|

|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
...
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
...
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
**    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 a memory
** allocation subsystem for use by SQLite.  
**
** $Id: mem2.c,v 1.4 2007/08/16 19:40:17 drh Exp $
*/

/*
** This version of the memory allocator is used only if the
** SQLITE_MEMDEBUG macro is defined and SQLITE_OMIT_MEMORY_ALLOCATION
** is not defined.
*/
................................................................................

/*
** Return the amount of memory currently checked out.
*/
sqlite3_uint64 sqlite3_memory_used(void){
  sqlite3_uint64 n;
  if( mem.mutex==0 ){
    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
  }
  sqlite3_mutex_enter(mem.mutex);
  n = mem.nowUsed;
  sqlite3_mutex_leave(mem.mutex);  
  return n;
}

/*
** Return the maximum amount of memory that has ever been
** checked out since either the beginning of this process
** or since the most recent reset.
*/
sqlite3_uint64 sqlite3_memory_highwater(int resetFlag){
  sqlite3_uint64 n;
  if( mem.mutex==0 ){
    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
  }
  sqlite3_mutex_enter(mem.mutex);
  n = mem.mxUsed;
  if( resetFlag ){
    mem.mxUsed = mem.nowUsed;
  }
  sqlite3_mutex_leave(mem.mutex);  
  return n;
}
................................................................................
*/
int sqlite3_memory_alarm(
  void(*xCallback)(void *pArg, sqlite3_uint64 used, unsigned int N),
  void *pArg,
  sqlite3_uint64 iThreshold
){
  if( mem.mutex==0 ){
    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
  }
  sqlite3_mutex_enter(mem.mutex);
  mem.alarmCallback = xCallback;
  mem.alarmArg = pArg;
  mem.alarmThreshold = iThreshold;
  sqlite3_mutex_leave(mem.mutex);
  return SQLITE_OK;
}

/*
** Trigger the alarm 
*/
static void sqlite3MemsysAlarm(unsigned nByte){
  void (*xCallback)(void*,sqlite3_uint64,unsigned);
  sqlite3_uint64 nowUsed;
  void *pArg;
  if( mem.alarmCallback==0 || mem.alarmBusy  ) return;
  mem.alarmBusy = 1;
  xCallback = mem.alarmCallback;
  nowUsed = mem.nowUsed;
  pArg = mem.alarmArg;
  sqlite3_mutex_leave(mem.mutex);
  xCallback(pArg, nowUsed, nByte);
  sqlite3_mutex_enter(mem.mutex);
  mem.alarmBusy = 0;
}

/*
** Given an allocation, find the MemBlockHdr for that allocation.
**
** This routine checks the guards at either end of the allocation and
................................................................................
  struct MemBlockHdr *pHdr;
  void **pBt;
  unsigned int *pInt;
  void *p;
  unsigned int totalSize;

  if( mem.mutex==0 ){
    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
  }
  sqlite3_mutex_enter(mem.mutex);
  if( mem.nowUsed+nByte>=mem.alarmThreshold ){
    sqlite3MemsysAlarm(nByte);
  }
  nByte = (nByte+3)&~3;
  totalSize = nByte + sizeof(*pHdr) + sizeof(unsigned int) +
               mem.nBacktrace*sizeof(void*);
  if( mem.iFail>0 ){
................................................................................
  if( pPrior==0 ){
    return;
  }
  assert( mem.mutex!=0 );
  pHdr = sqlite3MemsysGetHeader(pPrior);
  pBt = (void**)pHdr;
  pBt -= pHdr->nBacktraceSlots;
  sqlite3_mutex_enter(mem.mutex);
  mem.nowUsed -= pHdr->iSize;
  if( pHdr->pPrev ){
    assert( pHdr->pPrev->pNext==pHdr );
    pHdr->pPrev->pNext = pHdr->pNext;
  }else{
    assert( mem.pFirst==pHdr );
    mem.pFirst = pHdr->pNext;

Changes to src/mutex.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
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
110
111
112
113
114
115
116
117









118
119
120
121

122
123
124
125
126
127
128

129
130




131
132
133
134
135
136
137
138
139






















140
141
142









143
144





145



146
147
148
149
150


151
152




153
154



155
156
157


158





159
160

161
162
163
164
165
166
167






168
169

170
171
172
173

174
175
176
177
178
179
180
181
182






183
184




185










186















187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215
216




217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
**    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
** use by the SQLite core.
**
** $Id: mutex.c,v 1.2 2007/08/16 10:09:03 danielk1977 Exp $
*/

/*
** If SQLITE_MUTEX_APPDEF is defined, then this whole module is
** omitted and equivalent functionality just be provided by the
** application that links against the SQLite library.
*/
................................................................................
** in single threaded applications which do not want the extra overhead
** of thread locking primitives.
*/

/*
** 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 usually zero, which causes
** any space required for the mutex to be obtained from
** sqlite3_malloc().  However if the argument is a positive
** integer less than SQLITE_NUM_STATIC_MUTEX, then a pointer
** to a static mutex is returned.  There are a finite number
** of static mutexes.  Static mutexes should not be passed
** to sqlite3_mutex_free().  The allocation of a static
** mutex cannot fail.
*/
sqlite3_mutex *sqlite3_mutex_alloc(int idNotUsed){
  return (sqlite3_mutex*)sqlite3_mutex_alloc;
}

/*
** This routine deallocates a previously
** allocated mutex.  SQLite is careful to deallocate every
** mutex that it allocates.
*/
void sqlite3_mutex_free(sqlite3_mutex *pNotUsed){}

/*
** The sqlite3_mutex_enter() routine attempts to enter a
** mutex.  If another thread is already within the mutex,
** sqlite3_mutex_enter() will return SQLITE_BUSY if blockFlag
** is zero, or it will block and wait for the other thread to
** exit if blockFlag is non-zero.  Mutexes are recursive.  The
** same thread can enter a single mutex multiple times.  Each
** entrance must be matched with a corresponding exit before
** another thread is able to enter the mutex.

*/
int sqlite3_mutex_enter(sqlite3_mutex *pNotUsed, int blockFlag){
  return SQLITE_OK;
}

/*
** The sqlite3_mutex_exit() 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.
*/
void sqlite3_mutex_leave(sqlite3_mutex *pNotUsed){
  return;
}

/*
** The sqlite3_mutex_serialize() routine is used to serialize 
** execution of a subroutine.  The subroutine given in the argument
** is invoked.  But only one thread at a time is allowed to be
** running a subroutine using sqlite3_mutex_serialize().
*/
int sqlite3_mutex_serialize(void (*xCallback)(void*), void *pArg){
  xCallback(pArg);
  return SQLITE_OK;
}

#if 0
/**************** Non-recursive Pthread Mutex Implementation *****************
**
** This implementation of mutexes is built using a version of pthreads that
** does not have native support for recursive mutexes.
*/

/*
** Each recursive mutex is an instance of the following structure.
*/
struct RMutex {

  int nRef;                   /* Number of entrances */
  pthread_mutex_t auxMutex;   /* Mutex controlling access to nRef and owner */
  pthread_mutex_t mainMutex;  /* Mutex controlling the lock */
  pthread_t owner;            /* Thread that is within this mutex */
};

/*
** Static mutexes
*/









static struct RMutex rmutexes[] = {
  { 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, },
  { 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, },
  { 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, },

};

/*
** A mutex used for serialization.
*/
static RMutex serialMutex =
   {0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, };


/*




** 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 usually zero, which causes
** any space required for the mutex to be obtained from
** sqlite3_malloc().  However if the argument is a positive
** integer less than SQLITE_NUM_STATIC_MUTEX, then a pointer
** to a static mutex is returned.  There are a finite number






















** of static mutexes.  Static mutexes should not be passed
** to sqlite3_mutex_free().  The allocation of a static
** mutex cannot fail.









*/
sqlite3_mutex *sqlite3_mutex_alloc(int id){





  struct RMutex *p;



  if( id>0 ){
    if( id>sizeof(rmutexes)/sizeof(rmutexes[0]) ){
      p = 0;
    }else{
      p = &rmutexes[id-1];


    }
  }else{




    p = sqlite3_malloc( sizeof(*p) );
    if( p ){



      p->nRef = 0;
      pthread_mutex_init(&p->mutex, 0);
    }


  }





  return (sqlite3_mutex*)p;
}


/*
** This routine deallocates a previously
** allocated mutex.  SQLite is careful to deallocate every
** mutex that it allocates.
*/
void sqlite3_mutex_free(sqlite3_mutex *pMutex){






  struct RMutex *p = (struct RMutex*)pMutex;
  assert( p->nRef==0 );

  pthread_mutex_destroy(&p->mutex);
  sqlite3_free(p);
}


/*
** The sqlite3_mutex_enter() routine attempts to enter a
** mutex.  If another thread is already within the mutex,
** sqlite3_mutex_enter() will return SQLITE_BUSY if blockFlag
** is zero, or it will block and wait for the other thread to
** exit if blockFlag is non-zero.  Mutexes are recursive.  The
** same thread can enter a single mutex multiple times.  Each
** entrance must be matched with a corresponding exit before
** another thread is able to enter the mutex.






*/
int sqlite3_mutex_enter(sqlite3_mutex *pMutex, int blockFlag){




  struct RMutex *p = (struct RMutex*)pMutex;










  while(1){















    pthread_mutex_lock(&p->auxMutex);
    if( p->nRef==0 ){
      p->nRef++;
      p->owner = pthread_self();
      pthread_mutex_lock(&p->mainMutex);
      pthread_mutex_unlock(&p->auxMutex);
      return SQLITE_OK;
    }else if( pthread_equal(p->owner, pthread_self()) ){
      p->nRef++;
      pthread_mutex_unlock(&p->auxMutex);
      return SQLITE_OK;
    }else if( !blockFlag ){
      pthread_mutex_unlock(&p->auxMutex);
      return SQLITE_BUSY;
    }else{
      pthread_mutex_unlock(&p->auxMutex);
      pthread_mutex_lock(&p->mainMutex);
      pthread_mutex_unlock(&p->mainMutex);
    }
  }
  /* NOTREACHED */

}

/*
** The sqlite3_mutex_exit() 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.
*/
void sqlite3_mutex_leave(sqlite3_mutex *pMutex){




  struct RMutex *p = (struct RMutex*)pMutex;
  pthread_mutex_lock(&p->auxMutex);
  p->nRef--;
  if( p->nRef<=0 ){
    pthread_mutex_unlock(&p->mainMutex);
  }
  pthread_mutex_unlock(&p->auxMutex);
}

/*
** The sqlite3_mutex_serialize() routine is used to serialize 
** execution of a subroutine.  The subroutine given in the argument
** is invoked.  But only one thread at a time is allowed to be
** running a subroutine using sqlite3_mutex_serialize().
*/
int sqlite3_mutex_serialize(void (*xCallback)(void*), void *pArg){
  sqlite3_mutex_enter(&serialMutex, 1);
  xCallback(pArg);
  sqlite3_mutex_leave(&serialMutex);
}
#endif /* non-recursive pthreads */

#endif /* !defined(SQLITE_MUTEX_APPDEF) */







|







 







|
<
<
<
<
<
<
<
<
<






|
<
<




|
|
|
|
|
|
|
|
>

|
|
<







|
<
<
<
<
<
<
<
<
<
<
<
<
<












>







|

>
>
>
>
>
>
>
>
>
|
<
<
<
>



|

|
|
>


>
>
>
>




|
<
<
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
>
>
>
>
>
>
>
>
>

|
>
>
>
>
>
|
>
>
>
|
<
<
<
<
>
>
|
<
>
>
>
>
|
|
>
>
>
|
<
|
>
>
|
>
>
>
>
>
|

>







>
>
>
>
>
>
|
<
>
|
|
|
|
>

|
|
|
<
<
<
<
<
>
>
>
>
>
>

|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






<



|
<


<
<
<
<


<
>









>
>
>
>
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<




8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124




125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147


148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168




169
170
171

172
173
174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215
216
217





218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

263
264
265
266

267
268




269
270

271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292











293
294
295
296
**    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
** use by the SQLite core.
**
** $Id: mutex.c,v 1.3 2007/08/16 19:40:17 drh Exp $
*/

/*
** If SQLITE_MUTEX_APPDEF is defined, then this whole module is
** omitted and equivalent functionality just be provided by the
** application that links against the SQLite library.
*/
................................................................................
** in single threaded applications which do not want the extra overhead
** of thread locking primitives.
*/

/*
** 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. 









*/
sqlite3_mutex *sqlite3_mutex_alloc(int idNotUsed){
  return (sqlite3_mutex*)sqlite3_mutex_alloc;
}

/*
** This routine deallocates a previously allocated mutex.


*/
void sqlite3_mutex_free(sqlite3_mutex *pNotUsed){}

/*
** 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.
*/
void sqlite3_mutex_enter(sqlite3_mutex *pNotUsed){}
int sqlite3_mutex_try(sqlite3_mutex *pNotUsed){ return SQLITE_OK; }


/*
** The sqlite3_mutex_exit() 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.
*/
void sqlite3_mutex_leave(sqlite3_mutex *pNotUsed){}














#if 0
/**************** Non-recursive Pthread Mutex Implementation *****************
**
** This implementation of mutexes is built using a version of pthreads that
** does not have native support for recursive mutexes.
*/

/*
** Each recursive mutex is an instance of the following structure.
*/
struct RMutex {
  int recursiveMagic;         /* Magic number identifying this as recursive */
  int nRef;                   /* Number of entrances */
  pthread_mutex_t auxMutex;   /* Mutex controlling access to nRef and owner */
  pthread_mutex_t mainMutex;  /* Mutex controlling the lock */
  pthread_t owner;            /* Thread that is within this mutex */
};

/*
** Each fast mutex is an instance of the following structure
*/
struct FMutex {
  int fastMagic;          /* Identifies this as a fast mutex */
  pthread_mutex_t mutex;  /* The actual underlying mutex */
};

/*
** Either of the above
*/
union AnyMutex {
  struct RMutex r;



  struct FMutex f;
};

/*
** Magic numbers
*/
#define SQLITE_MTX_RECURSIVE   0x4ED886ED
#define SQLITE_MTX_STATIC      0x56FCE1B4
#define SQLITE_MTX_FAST        0x245BFD4F

/*
** Static mutexes
*/

/*
** 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:




**
** <ul>
** <li>  SQLITE_MUTEX_FAST               0
** <li>  SQLITE_MUTEX_RECURSIVE          1
** <li>  SQLITE_MUTEX_STATIC_MASTER      2
** <li>  SQLITE_MUTEX_STATIC_MEM         3
** <li>  SQLITE_MUTEX_STATIC_PRNG        4
** </ul>
**
** 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.  Three 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.
*/
sqlite3_mutex *sqlite3_mutex_alloc(int iType){
  static struct FMutex staticMutexes[] = {
    { SQLITE_MTX_STATIC, PTHREAD_MUTEX_INITIALIZER },
    { SQLITE_MTX_STATIC, PTHREAD_MUTEX_INITIALIZER },
    { SQLITE_MTX_STATIC, PTHREAD_MUTEX_INITIALIZER },
  };
  sqlite3_mutex *p;
  switch( iType ){
    case SQLITE_MUTEX_FAST: {
      struct FMutex *px = sqlite3_malloc( sizeof(*px) );
      if( px ){




        px->fastMagic = SQLITE_MTX_FAST;
        pthread_mutex_init(&px->mutex, 0);
      }

      p = (sqlite3_mutex*)px;
      break;
    }
    case SQLITE_MUTEX_RECURSIVE: {
      struct RMutex *px = sqlite3_malloc( sizeof(*px) );
      if( px ){
        px->recursiveMagic = SQLITE_MTX_RECURSIVE;
        pthread_mutex_init(&px->auxMutex, 0);
        pthread_mutex_init(&px->mainMutex, 0);
        px->nRef = 0;

      }
      p = (sqlite3_mutex*)px;
      break;
    }
    default: {
      p = &staticMutexes[iType-2];
      break;
    }
  }
  return p;
}


/*
** This routine deallocates a previously
** allocated mutex.  SQLite is careful to deallocate every
** mutex that it allocates.
*/
void sqlite3_mutex_free(sqlite3_mutex *pMutex){
  int iType = *(int*)pMutex;
  if( iType==SQLITE_MTX_FAST ){
    struct FMutex *p = (struct FMutex*)pMutex;
    pthread_mutex_destroy(&p->mutex);
    sqlite3_free(p);
  }else if( iType==SQLITE_MTX_RECURSIVE ){
    struct RMutex *p = (struct RMutex*)pMutex;

    pthread_mutex_destroy(&p->auxMutex);
    pthread_mutex_destroy(&p->mainMutex);
    sqlite3_free(p);
  }
}

/*
** 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.
*/
void sqlite3_mutex_enter(sqlite3_mutex *pMutex){
  if( SQLITE_MTX_FAST == *(int*)pMutex ){
    struct FMutex *p = (struct FMutex*)pMutex;
    pthread_mutex_lock(&p->mutex);
  }else{
    struct RMutex *p = (struct RMutex*)pMutex;
    pthread_mutex_lock(&p->auxMutex);
    if( p->nRef==0 ){
      p->nRef++;
      p->owner = pthread_self();
      pthread_mutex_lock(&p->mainMutex);
      pthread_mutex_unlock(&p->auxMutex);
    }else if( pthread_equal(p->owner, pthread_self()) ){
      p->nRef++;
      pthread_mutex_unlock(&p->auxMutex);
    }else{
      while( p->nRef ){
        pthread_mutex_unlock(&p->auxMutex);
        pthread_mutex_lock(&p->mainMutex);
        pthread_mutex_unlock(&p->mainMutex);
      }
    }
  }
}
int sqlite3_mutex_try(sqlite3_mutex *pMutex){
  if( SQLITE_MTX_FAST == *(int*)pMutex ){
    struct FMutex *p = (struct FMutex*)pMutex;
    if( pthread_mutex_trylock(&p->mutex) ){
      return SQLITE_BUSY;
    }
  }else{
    struct RMutex *p = (struct RMutex*)pMutex;
    pthread_mutex_lock(&p->auxMutex);
    if( p->nRef==0 ){
      p->nRef++;
      p->owner = pthread_self();
      pthread_mutex_lock(&p->mainMutex);
      pthread_mutex_unlock(&p->auxMutex);

    }else if( pthread_equal(p->owner, pthread_self()) ){
      p->nRef++;
      pthread_mutex_unlock(&p->auxMutex);
    }else{

      pthread_mutex_unlock(&p->auxMutex);
      return SQLITE_BUSY;




    }
  }

  return SQLITE_OK;
}

/*
** The sqlite3_mutex_exit() 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.
*/
void sqlite3_mutex_leave(sqlite3_mutex *pMutex){
  if( SQLITE_MTX_FAST == *(int*)pMutex ){
    struct FMutex *p = (struct FMutex*)pMutex;
    pthread_mutex_unlock(&p->mutex);
  }else{
    struct RMutex *p = (struct RMutex*)pMutex;
    pthread_mutex_lock(&p->auxMutex);
    p->nRef--;
    if( p->nRef<=0 ){
      pthread_mutex_unlock(&p->mainMutex);
    }
    pthread_mutex_unlock(&p->auxMutex);
  }











}
#endif /* non-recursive pthreads */

#endif /* !defined(SQLITE_MUTEX_APPDEF) */

Changes to src/sqlite.h.in.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
504
505
506
507
508
509
510


511
512
513
514
515
516
517
518
519
520
521



522
523
524
525
526
527
528
529
530


531
532
533
534
535
536
537
538
539
540
541
....
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
3219
3220
3221
3222
3223
3224
3225
3226
3227

3228
3229





3230
3231
3232
3233
3234
3235
3236
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
** @(#) $Id: sqlite.h.in,v 1.225 2007/08/16 13:01:45 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
/*
** CAPI3REF: Mutex Handle
**
** The mutex module within SQLite defines [sqlite3_mutex] to be an
** abstract type for a mutex object.  The SQLite core never looks
** at the internal representation of an [sqlite3_mutex].  It only
** deals with pointers to the [sqlite3_mutex] object.


*/
typedef struct sqlite3_mutex sqlite3_mutex;

/*
** CAPI3REF: OS Interface Object
**
** An instance of this object defines the interface between the
** SQLite core and the underlying operating system.  The "vfs"
** in the name of the object stands for "virtual file system".
**
** The iVersion field is initially 1 but may be larger for future



** versions.  szOsFile is the size of the subclassed sqlite3_file
** structure used by this VFS.  mxPathname is the maximum length of
** a pathname in this VFS.
**
** The nRef field is incremented and decremented by SQLite to keep
** count of the number of users of the VFS.  This field and
** vfsMutex, pNext, and pPrev are the only fields in the sqlite3_vfs 
** structure that SQLite will ever modify.  These fields are modified 
** within an sqlite3_mutex_serialize() call so that updates are threadsafe.


** 
** The sqlite3_vfs.vfsMutex is a mutex used by the OS interface.
** It should initially be NULL.  SQLite will initialize this field
** using sqlite3_mutex_allocate() upon first use of the adaptor
** by sqlite3_open_v2() and will deallocate the mutex when the
** last user closes.  In other words, vfsMutex will be allocated
** when nRef transitions from 0 to 1 and will be deallocated when
** nRef transitions from 1 to 0.
**
** Registered vfs modules are kept on a linked list formed by
** the pNext and pPrev pointers.  The [sqlite3_register_vfs()]
................................................................................
** references in the SQLite library for which implementations
** must be provided by the application.
**
** 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 usually zero, which causes
** any space required for the mutex to be obtained from
** sqlite3_malloc().  However if the argument is a positive


** integer less than or equal to SQLITE_MUTEX_STATIC_MAX, then a pointer
** to a static mutex is returned.  There are a finite number

















** of static mutexes.  Static mutexes should not be passed
** to sqlite3_mutex_free().  Static mutexes are used internally
** by the SQLite core and should not be used by the application.



**






** The sqlite3_mutex_free() routine deallocates a previously
** allocated mutex.  SQLite is careful to deallocate every
** mutex that it allocates.


**
** The sqlite3_mutex_enter() routine attempts to enter a
** mutex.  If another thread is already within the mutex,
** sqlite3_mutex_enter() will return SQLITE_BUSY if blockFlag
** is zero, or it will block and wait for the other thread to
** exit if blockFlag is non-zero.  Mutexes are recursive.  The
** same thread can enter a single mutex multiple times.  Each
** entrance must be matched with a corresponding exit before
** another thread is able to enter the mutex.







**
** The sqlite3_mutex_exit() 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.
**
** The sqlite3_mutex_serialize() routine is used to serialize 
** a subroutine.  The subroutine given in the argument is invoked
** while holding a static mutex.  This ensures that no other
** thread is running this same subroutine at the same time.
*/
sqlite3_mutex *sqlite3_mutex_alloc(int);
void sqlite3_mutex_free(sqlite3_mutex*);
int sqlite3_mutex_enter(sqlite3_mutex*, int blockFlag);

void sqlite3_mutex_leave(sqlite3_mutex*);
int sqlite3_mutex_serialize(void(*)(void*), void*);







/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT







|







 







>
>











>
>
>
|






|
|
>
>



|







 







|
|
|
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
>
>
>

>
>
>
>
>
>

|
|
>
>

|
|
|
<
<
<
<
<
>
>
>
>
>
>
>





<
<
<
<
<



|
>

<
>
>
>
>
>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
....
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
3219
3220
3221
3222
3223


3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242





3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254





3255
3256
3257
3258
3259
3260

3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
** @(#) $Id: sqlite.h.in,v 1.226 2007/08/16 19:40:17 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
/*
** CAPI3REF: Mutex Handle
**
** The mutex module within SQLite defines [sqlite3_mutex] to be an
** abstract type for a mutex object.  The SQLite core never looks
** at the internal representation of an [sqlite3_mutex].  It only
** deals with pointers to the [sqlite3_mutex] object.
**
** Mutexes are created using [sqlite3_mutex_alloc()].
*/
typedef struct sqlite3_mutex sqlite3_mutex;

/*
** CAPI3REF: OS Interface Object
**
** An instance of this object defines the interface between the
** SQLite core and the underlying operating system.  The "vfs"
** in the name of the object stands for "virtual file system".
**
** The iVersion field is initially 1 but may be larger for future
** versions of SQLite.  Additional fields may be appended to this
** object when the iVersion value is increased.
**
** The szOsFile field is the size of the subclassed sqlite3_file
** structure used by this VFS.  mxPathname is the maximum length of
** a pathname in this VFS.
**
** The nRef field is incremented and decremented by SQLite to keep
** count of the number of users of the VFS.  This field and
** vfsMutex, pNext, and pPrev are the only fields in the sqlite3_vfs 
** structure that SQLite will ever modify.  SQLite will only access
** or modify these fields while holding a particular static mutex.
** The application should never modify any fields of the sqlite3_vfs
** object once the object has been registered.
** 
** The sqlite3_vfs.vfsMutex is a mutex used by the OS interface.
** It should initially be NULL.  SQLite will initialize this field
** using sqlite3_mutex_alloc() upon first use of the adaptor
** by sqlite3_open_v2() and will deallocate the mutex when the
** last user closes.  In other words, vfsMutex will be allocated
** when nRef transitions from 0 to 1 and will be deallocated when
** nRef transitions from 1 to 0.
**
** Registered vfs modules are kept on a linked list formed by
** the pNext and pPrev pointers.  The [sqlite3_register_vfs()]
................................................................................
** references in the SQLite library for which implementations
** must be provided by the application.
**
** 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:
**
** <ul>
** <li>  SQLITE_MUTEX_FAST
** <li>  SQLITE_MUTEX_RECURSIVE
** <li>  SQLITE_MUTEX_STATIC_MASTER

** <li>  SQLITE_MUTEX_STATIC_MEM
** <li>  SQLITE_MUTEX_STATIC_PRNG
** </ul>
**
** 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.  Three 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.
**
** The sqlite3_mutex_free() routine deallocates a previously
** allocated dynamic mutex.  SQLite is careful to deallocate every
** dynamic mutex that it allocates.  The dynamic mutexes must not be in 
** use when they are deallocated.  Static mutexes do not need to be
** deallocated and SQLite never bothers to do so.
**
** 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.   SQLite will never exhibit
** such behavior in its own use of mutexes.
**
** The sqlite3_mutex_exit() 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.





*/
sqlite3_mutex *sqlite3_mutex_alloc(int);
void sqlite3_mutex_free(sqlite3_mutex*);
void sqlite3_mutex_enter(sqlite3_mutex*);
int sqlite3_mutex_try(sqlite3_mutex*);
void sqlite3_mutex_leave(sqlite3_mutex*);

#define SQLITE_MUTEX_FAST             0
#define SQLITE_MUTEX_RECURSIVE        1
#define SQLITE_MUTEX_STATIC_MASTER    2
#define SQLITE_MUTEX_STATIC_MEM       3
#define SQLITE_MUTEX_STATIC_PRNG      4


/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT