Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Implement the 'CONFIG_SINGLETHREAD' and 'CONFIG_MULTITHREAD' configuration modes. (CVS 5234) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
5059644c4bc5f6679afd939e0bc26080 |
User & Date: | danielk1977 2008-06-18 17:09:10.000 |
Context
2008-06-18
| ||
17:59 | Fix a test case in mutex1.test that was failing when sqlite was compiled with SQLITE_THREADSAFE=0. (CVS 5235) (check-in: d1a87c3bcc user: danielk1977 tags: trunk) | |
17:09 | Implement the 'CONFIG_SINGLETHREAD' and 'CONFIG_MULTITHREAD' configuration modes. (CVS 5234) (check-in: 5059644c4b user: danielk1977 tags: trunk) | |
15:34 | Make sure aggregate functions can take any number of arguments up to the limit imposed by SQLITE_LIMIT_FUNCTION_ARGS. Ticket #3179. Modify the group_concat() function to take an unlimited number of arguments in order to facilitate testing this behavior. (CVS 5233) (check-in: 70c6739f4e user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2004 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** $Id: btree.c,v 1.466 2008/06/18 17:09:10 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ #include "btreeInt.h" |
︙ | ︙ | |||
1197 1198 1199 1200 1201 1202 1203 | db->flags |= SQLITE_SharedCache; } if( !zFullPathname ){ sqlite3_free(p); return SQLITE_NOMEM; } sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); | | | 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 | db->flags |= SQLITE_SharedCache; } if( !zFullPathname ){ sqlite3_free(p); return SQLITE_NOMEM; } sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); sqlite3_mutex_enter(mutexShared); for(pBt=sqlite3SharedCacheList; pBt; pBt=pBt->pNext){ assert( pBt->nRef>0 ); if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager)) && sqlite3PagerVfs(pBt->pPager)==pVfs ){ p->pBt = pBt; pBt->nRef++; |
︙ | ︙ | |||
1294 1295 1296 1297 1298 1299 1300 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) /* Add the new BtShared object to the linked list sharable BtShareds. */ if( p->sharable ){ sqlite3_mutex *mutexShared; pBt->nRef = 1; | | | | | 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) /* Add the new BtShared object to the linked list sharable BtShareds. */ if( p->sharable ){ sqlite3_mutex *mutexShared; pBt->nRef = 1; mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); if( SQLITE_THREADSAFE && sqlite3Config.bCoreMutex ){ pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST); if( pBt->mutex==0 ){ rc = SQLITE_NOMEM; db->mallocFailed = 0; goto btree_open_out; } } sqlite3_mutex_enter(mutexShared); |
︙ | ︙ | |||
1369 1370 1371 1372 1373 1374 1375 | static int removeFromSharingList(BtShared *pBt){ #ifndef SQLITE_OMIT_SHARED_CACHE sqlite3_mutex *pMaster; BtShared *pList; int removed = 0; assert( sqlite3_mutex_notheld(pBt->mutex) ); | | | 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 | static int removeFromSharingList(BtShared *pBt){ #ifndef SQLITE_OMIT_SHARED_CACHE sqlite3_mutex *pMaster; BtShared *pList; int removed = 0; assert( sqlite3_mutex_notheld(pBt->mutex) ); pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); sqlite3_mutex_enter(pMaster); pBt->nRef--; if( pBt->nRef<=0 ){ if( sqlite3SharedCacheList==pBt ){ sqlite3SharedCacheList = pBt->pNext; }else{ pList = sqlite3SharedCacheList; |
︙ | ︙ |
Changes to src/date.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This file contains the C functions that implement date and time ** functions for SQLite. ** ** There is only one exported symbol in this file - the function ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This file contains the C functions that implement date and time ** functions for SQLite. ** ** There is only one exported symbol in this file - the function ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** ** $Id: date.c,v 1.85 2008/06/18 17:09:10 danielk1977 Exp $ ** ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon ** in Greenwich on November 24, 4714 B.C. according to the Gregorian ** calendar system. ** ** 1970-01-01 00:00:00 is JD 2440587.5 |
︙ | ︙ | |||
470 471 472 473 474 475 476 | y.h = sLocal.tm_hour; y.m = sLocal.tm_min; y.s = sLocal.tm_sec; } #else { struct tm *pTm; | | | | 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 | y.h = sLocal.tm_hour; y.m = sLocal.tm_min; y.s = sLocal.tm_sec; } #else { struct tm *pTm; sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); pTm = localtime(&t); y.Y = pTm->tm_year + 1900; y.M = pTm->tm_mon + 1; y.D = pTm->tm_mday; y.h = pTm->tm_hour; y.m = pTm->tm_min; y.s = pTm->tm_sec; sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); } #endif y.validYMD = 1; y.validHMS = 1; y.validJD = 0; y.validTZ = 0; computeJD(&y); |
︙ | ︙ | |||
1027 1028 1029 1030 1031 1032 1033 | struct tm sNow; gmtime_r(&t, &sNow); strftime(zBuf, 20, zFormat, &sNow); } #else { struct tm *pTm; | | | | 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 | struct tm sNow; gmtime_r(&t, &sNow); strftime(zBuf, 20, zFormat, &sNow); } #else { struct tm *pTm; sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); pTm = gmtime(&t); strftime(zBuf, 20, zFormat, pTm); sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); } #endif sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); } #endif |
︙ | ︙ |
Changes to src/loadext.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to dynamically load extensions into ** the SQLite library. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to dynamically load extensions into ** the SQLite library. ** ** $Id: loadext.c,v 1.49 2008/06/18 17:09:10 danielk1977 Exp $ */ #ifndef SQLITE_CORE #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */ #endif #include "sqlite3ext.h" #include "sqliteInt.h" |
︙ | ︙ | |||
474 475 476 477 478 479 480 | if( rc ){ return rc; }else #endif { int i; #ifndef SQLITE_MUTEX_NOOP | | | 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 | if( rc ){ return rc; }else #endif { int i; #ifndef SQLITE_MUTEX_NOOP sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); #endif sqlite3_mutex_enter(mutex); for(i=0; i<autoext.nExt; i++){ if( autoext.aExt[i]==xInit ) break; } if( i==autoext.nExt ){ int nByte = (autoext.nExt+1)*sizeof(autoext.aExt[0]); |
︙ | ︙ | |||
507 508 509 510 511 512 513 | */ void sqlite3_reset_auto_extension(void){ #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize()==SQLITE_OK ) #endif { #ifndef SQLITE_MUTEX_NOOP | | | 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 | */ void sqlite3_reset_auto_extension(void){ #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize()==SQLITE_OK ) #endif { #ifndef SQLITE_MUTEX_NOOP sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); #endif sqlite3_mutex_enter(mutex); sqlite3_free(autoext.aExt); autoext.aExt = 0; autoext.nExt = 0; sqlite3_mutex_leave(mutex); } |
︙ | ︙ | |||
533 534 535 536 537 538 539 | if( autoext.nExt==0 ){ /* Common case: early out without every having to acquire a mutex */ return SQLITE_OK; } for(i=0; go; i++){ char *zErrmsg = 0; #ifndef SQLITE_MUTEX_NOOP | | | 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 | if( autoext.nExt==0 ){ /* Common case: early out without every having to acquire a mutex */ return SQLITE_OK; } for(i=0; go; i++){ char *zErrmsg = 0; #ifndef SQLITE_MUTEX_NOOP sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); #endif sqlite3_mutex_enter(mutex); if( i>=autoext.nExt ){ xInit = 0; go = 0; }else{ xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.449 2008/06/18 17:09:10 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> #ifdef SQLITE_ENABLE_FTS3 # include "fts3.h" #endif |
︙ | ︙ | |||
72 73 74 75 76 77 78 | ** or for the first call after a call to sqlite3_shutdown. */ int sqlite3_initialize(void){ int rc; if( sqlite3IsInit ) return SQLITE_OK; rc = sqlite3_mutex_init(); if( rc==SQLITE_OK ){ | | | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | ** or for the first call after a call to sqlite3_shutdown. */ int sqlite3_initialize(void){ int rc; if( sqlite3IsInit ) return SQLITE_OK; rc = sqlite3_mutex_init(); if( rc==SQLITE_OK ){ sqlite3_mutex *pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); sqlite3_mutex_enter(pMutex); if( sqlite3IsInit==0 ){ sqlite3IsInit = 1; if( rc==SQLITE_OK ) rc = sqlite3MallocInit(); if( rc==SQLITE_OK ) rc = sqlite3_os_init(); if( rc!=SQLITE_OK ){ sqlite3IsInit = 0; |
︙ | ︙ | |||
1204 1205 1206 1207 1208 1209 1210 | SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_MASTER_JOURNAL ); /* Allocate the sqlite data structure */ db = sqlite3MallocZero( sizeof(sqlite3) ); if( db==0 ) goto opendb_out; | > | > | 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 | SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_MASTER_JOURNAL ); /* Allocate the sqlite data structure */ db = sqlite3MallocZero( sizeof(sqlite3) ); if( db==0 ) goto opendb_out; if( sqlite3Config.bFullMutex ){ db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); if( db->mutex==0 ){ sqlite3_free(db); db = 0; goto opendb_out; } } sqlite3_mutex_enter(db->mutex); db->errMask = 0xff; db->priorNewRowid = 0; db->nDb = 2; db->magic = SQLITE_MAGIC_BUSY; db->aDb = db->aDbStatic; assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); |
︙ | ︙ | |||
1359 1360 1361 1362 1363 1364 1365 | db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), SQLITE_DEFAULT_LOCKING_MODE); #endif opendb_out: if( db ){ | | | 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 | db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), SQLITE_DEFAULT_LOCKING_MODE); #endif opendb_out: if( db ){ assert( db->mutex!=0 || sqlite3Config.bFullMutex==0 ); sqlite3_mutex_leave(db->mutex); } if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){ sqlite3_close(db); db = 0; } *ppDb = db; |
︙ | ︙ |
Changes to src/malloc.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** Memory allocation functions used throughout sqlite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** Memory allocation functions used throughout sqlite. ** ** $Id: malloc.c,v 1.19 2008/06/18 17:09:10 danielk1977 Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> /* ** This routine runs when the memory allocator sees that the |
︙ | ︙ | |||
98 99 100 101 102 103 104 | ** Initialize the memory allocation subsystem. */ int sqlite3MallocInit(void){ if( sqlite3Config.m.xMalloc==0 ){ sqlite3MemSetDefault(); } memset(&mem0, 0, sizeof(mem0)); | | | | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | ** Initialize the memory allocation subsystem. */ int sqlite3MallocInit(void){ if( sqlite3Config.m.xMalloc==0 ){ sqlite3MemSetDefault(); } memset(&mem0, 0, sizeof(mem0)); if( sqlite3Config.bMemstat ){ mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); } return sqlite3Config.m.xInit(sqlite3Config.m.pAppData); } /* ** Deinitialize the memory allocation subsystem. */ |
︙ | ︙ |
Changes to src/mem2.c.
︙ | ︙ | |||
15 16 17 18 19 20 21 | ** to obtain the memory it needs while adding lots of additional debugging ** information to each allocation in order to help detect and fix memory ** leaks and memory usage errors. ** ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. ** | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | ** to obtain the memory it needs while adding lots of additional debugging ** information to each allocation in order to help detect and fix memory ** leaks and memory usage errors. ** ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. ** ** $Id: mem2.c,v 1.32 2008/06/18 17:09:10 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** This version of the memory allocator is used only if the ** SQLITE_MEMDEBUG macro is defined */ |
︙ | ︙ | |||
158 159 160 161 162 163 164 | return pHdr->iSize; } /* ** Initialize the memory allocation subsystem. */ static int sqlite3MemInit(void *NotUsed){ | | | 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | return pHdr->iSize; } /* ** Initialize the memory allocation subsystem. */ static int sqlite3MemInit(void *NotUsed){ mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); return SQLITE_OK; } /* ** Deinitialize the memory allocation subsystem. */ static void sqlite3MemShutdown(void *NotUsed){ |
︙ | ︙ |
Changes to src/mem3.c.
︙ | ︙ | |||
16 17 18 19 20 21 22 | ** use of malloc(). All dynamically allocatable memory is ** contained in a static array, mem.aPool[]. The size of this ** fixed memory pool is SQLITE_MEMORY_SIZE bytes. ** ** This version of the memory allocation subsystem is used if ** and only if SQLITE_MEMORY_SIZE is defined. ** | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ** use of malloc(). All dynamically allocatable memory is ** contained in a static array, mem.aPool[]. The size of this ** fixed memory pool is SQLITE_MEMORY_SIZE bytes. ** ** This version of the memory allocation subsystem is used if ** and only if SQLITE_MEMORY_SIZE is defined. ** ** $Id: mem3.c,v 1.14 2008/06/18 17:09:10 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** This version of the memory allocator is used only when ** SQLITE_MEMORY_SIZE is defined. */ |
︙ | ︙ | |||
210 211 212 213 214 215 216 | ** Enter the mutex mem.mutex. Allocate it if it is not already allocated. ** ** Also: Initialize the memory allocation subsystem the first time ** this routine is called. */ static void memsys3Enter(void){ if( mem.mutex==0 ){ | | | 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | ** Enter the mutex mem.mutex. Allocate it if it is not already allocated. ** ** Also: Initialize the memory allocation subsystem the first time ** this routine is called. */ static void memsys3Enter(void){ if( mem.mutex==0 ){ mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); mem.aPool[0].u.hdr.size4x = SQLITE_MEMORY_SIZE/2 + 2; mem.aPool[SQLITE_MEMORY_SIZE/8].u.hdr.prevSize = SQLITE_MEMORY_SIZE/8; mem.aPool[SQLITE_MEMORY_SIZE/8].u.hdr.size4x = 1; mem.iMaster = 1; mem.szMaster = SQLITE_MEMORY_SIZE/8; mem.mnMaster = mem.szMaster; } |
︙ | ︙ |
Changes to src/mem4.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** 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. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** 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: mem4.c,v 1.3 2008/06/18 17:09:10 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** This version of the memory allocator attempts to obtain memory ** from mmap() if the size of the allocation is close to the size ** of a virtual memory page. If the size of the allocation is different |
︙ | ︙ | |||
108 109 110 111 112 113 114 | /* ** Enter the mutex mem.mutex. Allocate it if it is not already allocated. ** The mmap() region is initialized the first time this routine is called. */ static void memsys4Enter(void){ if( mem.mutex==0 ){ | | | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | /* ** Enter the mutex mem.mutex. Allocate it if it is not already allocated. ** The mmap() region is initialized the first time this routine is called. */ static void memsys4Enter(void){ if( mem.mutex==0 ){ mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); } sqlite3_mutex_enter(mem.mutex); } /* ** Attempt to free memory to the mmap heap. This only works if ** the pointer p is within the range of memory addresses that |
︙ | ︙ |
Changes to src/mem5.c.
︙ | ︙ | |||
16 17 18 19 20 21 22 | ** use of malloc(). All dynamically allocatable memory is ** contained in a static array, mem.aPool[]. The size of this ** fixed memory pool is SQLITE_POW2_MEMORY_SIZE bytes. ** ** This version of the memory allocation subsystem is used if ** and only if SQLITE_POW2_MEMORY_SIZE is defined. ** | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ** use of malloc(). All dynamically allocatable memory is ** contained in a static array, mem.aPool[]. The size of this ** fixed memory pool is SQLITE_POW2_MEMORY_SIZE bytes. ** ** This version of the memory allocation subsystem is used if ** and only if SQLITE_POW2_MEMORY_SIZE is defined. ** ** $Id: mem5.c,v 1.6 2008/06/18 17:09:10 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** This version of the memory allocator is used only when ** SQLITE_POW2_MEMORY_SIZE is defined. */ |
︙ | ︙ | |||
189 190 191 192 193 194 195 | */ static void memsys5Enter(void){ if( mem.mutex==0 ){ int i; assert( sizeof(Mem5Block)==POW2_MIN ); assert( (SQLITE_POW2_MEMORY_SIZE % POW2_MAX)==0 ); assert( SQLITE_POW2_MEMORY_SIZE>=POW2_MAX ); | | | 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | */ static void memsys5Enter(void){ if( mem.mutex==0 ){ int i; assert( sizeof(Mem5Block)==POW2_MIN ); assert( (SQLITE_POW2_MEMORY_SIZE % POW2_MAX)==0 ); assert( SQLITE_POW2_MEMORY_SIZE>=POW2_MAX ); mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); sqlite3_mutex_enter(mem.mutex); for(i=0; i<NSIZE; i++) mem.aiFreelist[i] = -1; for(i=0; i<=NBLOCK-SZ_MAX; i += SZ_MAX){ mem.aCtrl[i] = (NSIZE-1) | CTRL_FREE; memsys5Link(i, NSIZE-1); } }else{ |
︙ | ︙ |
Changes to src/mutex.c.
︙ | ︙ | |||
15 16 17 18 19 20 21 | ** exclusion and is thus suitable for use only in applications ** that use SQLite in a single thread. But this implementation ** does do a lot of error checking on mutexes to make sure they ** are called correctly and at appropriate times. Hence, this ** implementation is suitable for testing. ** debugging purposes ** | | | > | > > > > > > > > | 15 16 17 18 19 20 21 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 | ** exclusion and is thus suitable for use only in applications ** that use SQLite in a single thread. But this implementation ** does do a lot of error checking on mutexes to make sure they ** are called correctly and at appropriate times. Hence, this ** implementation is suitable for testing. ** debugging purposes ** ** $Id: mutex.c,v 1.24 2008/06/18 17:09:10 danielk1977 Exp $ */ #include "sqliteInt.h" #ifndef SQLITE_MUTEX_NOOP /* ** Initialize the mutex system. */ int sqlite3_mutex_init(void){ int rc = SQLITE_OK; if( sqlite3Config.bCoreMutex ){ if( !sqlite3Config.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 sqlite3Config structure. ** ** The danger is that although sqlite3_config() is not a threadsafe ** API, sqlite3_initialize() is, and so multiple threads may be ** attempting to run this function simultaneously. To guard write ** access to the sqlite3Config structure, the 'MASTER' static mutex ** is obtained before modifying it. */ sqlite3_mutex_methods *p = sqlite3DefaultMutex(); sqlite3_mutex *pMaster = 0; rc = p->xMutexInit(); if( rc==SQLITE_OK ){ pMaster = p->xMutexAlloc(SQLITE_MUTEX_STATIC_MASTER); assert(pMaster); p->xMutexEnter(pMaster); assert( sqlite3Config.mutex.xMutexAlloc==0 || sqlite3Config.mutex.xMutexAlloc==p->xMutexAlloc ); if( !sqlite3Config.mutex.xMutexAlloc ){ sqlite3Config.mutex = *p; } p->xMutexLeave(pMaster); } }else{ rc = sqlite3Config.mutex.xMutexInit(); } } return rc; } /* ** Shutdown the mutex system. This call frees resources allocated by ** sqlite3_mutex_init(). */ int sqlite3_mutex_end(void){ int rc = SQLITE_OK; rc = sqlite3Config.mutex.xMutexEnd(); return rc; } /* ** Retrieve a pointer to a static mutex or allocate a new dynamic one. */ sqlite3_mutex *sqlite3_mutex_alloc(int id){ return sqlite3Config.mutex.xMutexAlloc(id); } sqlite3_mutex *sqlite3MutexAlloc(int id){ if( !sqlite3Config.bCoreMutex ){ return 0; } return sqlite3Config.mutex.xMutexAlloc(id); } /* ** Free a dynamic mutex. */ void sqlite3_mutex_free(sqlite3_mutex *p){ if( p ){ sqlite3Config.mutex.xMutexFree(p); |
︙ | ︙ |
Changes to src/os.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ****************************************************************************** ** ** This file contains OS interface code that is common to all ** architectures. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ****************************************************************************** ** ** This file contains OS interface code that is common to all ** architectures. ** ** $Id: os.c,v 1.114 2008/06/18 17:09:10 danielk1977 Exp $ */ #define _SQLITE_OS_C_ 1 #include "sqliteInt.h" #undef _SQLITE_OS_C_ /* ** The default SQLite sqlite3_vfs implementations do not allocate |
︙ | ︙ | |||
203 204 205 206 207 208 209 | sqlite3_mutex *mutex; #endif #ifndef SQLITE_OMIT_AUTOINIT int rc = sqlite3_initialize(); if( rc ) return 0; #endif #ifndef SQLITE_MUTEX_NOOP | | | | 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 | sqlite3_mutex *mutex; #endif #ifndef SQLITE_OMIT_AUTOINIT int rc = sqlite3_initialize(); if( rc ) return 0; #endif #ifndef SQLITE_MUTEX_NOOP mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); #endif sqlite3_vfs *pVfs = 0; static int isInit = 0; sqlite3_mutex_enter(mutex); if( !isInit ){ vfsList = sqlite3OsDefaultVfs(); isInit = 1; } for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){ if( zVfs==0 ) break; if( strcmp(zVfs, pVfs->zName)==0 ) break; } sqlite3_mutex_leave(mutex); return pVfs; } /* ** Unlink a VFS from the linked list */ static void vfsUnlink(sqlite3_vfs *pVfs){ assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) ); if( pVfs==0 ){ /* No-op */ }else if( vfsList==pVfs ){ vfsList = pVfs->pNext; }else if( vfsList ){ sqlite3_vfs *p = vfsList; while( p->pNext && p->pNext!=pVfs ){ |
︙ | ︙ | |||
254 255 256 257 258 259 260 | sqlite3_mutex *mutex; #endif #ifndef SQLITE_OMIT_AUTOINIT int rc = sqlite3_initialize(); if( rc ) return rc; #endif #ifndef SQLITE_MUTEX_NOOP | | | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | sqlite3_mutex *mutex; #endif #ifndef SQLITE_OMIT_AUTOINIT int rc = sqlite3_initialize(); if( rc ) return rc; #endif #ifndef SQLITE_MUTEX_NOOP mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); #endif sqlite3_vfs_find(0); /* Make sure we are initialized */ sqlite3_mutex_enter(mutex); vfsUnlink(pVfs); if( makeDflt || vfsList==0 ){ pVfs->pNext = vfsList; vfsList = pVfs; |
︙ | ︙ | |||
276 277 278 279 280 281 282 | } /* ** Unregister a VFS so that it is no longer accessible. */ int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ #ifndef SQLITE_MUTEX_NOOP | | | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | } /* ** Unregister a VFS so that it is no longer accessible. */ int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ #ifndef SQLITE_MUTEX_NOOP sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); #endif sqlite3_mutex_enter(mutex); vfsUnlink(pVfs); sqlite3_mutex_leave(mutex); return SQLITE_OK; } |
︙ | ︙ |
Changes to src/os_unix.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ****************************************************************************** ** ** This file contains code that is specific to Unix systems. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ****************************************************************************** ** ** This file contains code that is specific to Unix systems. ** ** $Id: os_unix.c,v 1.188 2008/06/18 17:09:10 danielk1977 Exp $ */ #include "sqliteInt.h" #if OS_UNIX /* This file is used on unix only */ /* #define SQLITE_ENABLE_LOCKING_STYLE 0 */ /* |
︙ | ︙ | |||
363 364 365 366 367 368 369 | } sqlite3LockingStyle; #endif /* SQLITE_ENABLE_LOCKING_STYLE */ /* ** Helper functions to obtain and relinquish the global mutex. */ static void enterMutex(){ | | | | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 | } sqlite3LockingStyle; #endif /* SQLITE_ENABLE_LOCKING_STYLE */ /* ** Helper functions to obtain and relinquish the global mutex. */ static void enterMutex(){ sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); } static void leaveMutex(){ sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); } #if SQLITE_THREADSAFE /* ** This variable records whether or not threads can override each others ** locks. ** |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.459 2008/06/18 17:09:10 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include <assert.h> #include <string.h> /* |
︙ | ︙ | |||
514 515 516 517 518 519 520 | */ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT static void pagerEnter(Pager *p){ p->iInUseDB++; if( p->iInUseMM && p->iInUseDB==1 ){ #ifndef SQLITE_MUTEX_NOOP sqlite3_mutex *mutex; | | | 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 | */ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT static void pagerEnter(Pager *p){ p->iInUseDB++; if( p->iInUseMM && p->iInUseDB==1 ){ #ifndef SQLITE_MUTEX_NOOP sqlite3_mutex *mutex; mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM2); #endif p->iInUseDB = 0; sqlite3_mutex_enter(mutex); p->iInUseDB = 1; sqlite3_mutex_leave(mutex); } assert( p->iInUseMM==0 ); |
︙ | ︙ | |||
612 613 614 615 616 617 618 | ** memory-management is enabled, also add the page to the global ** list of free pages. */ static void lruListAdd(PgHdr *pPg){ listAdd(&pPg->pPager->lru, &pPg->free, pPg); #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT if( !pPg->pPager->memDb ){ | | | | | | | | 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 | ** memory-management is enabled, also add the page to the global ** list of free pages. */ static void lruListAdd(PgHdr *pPg){ listAdd(&pPg->pPager->lru, &pPg->free, pPg); #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT if( !pPg->pPager->memDb ){ sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU)); listAdd(&sqlite3LruPageList, &pPg->gfree, pPg); sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU)); } #endif } /* ** Remove page pPg from the list of free pages for the associated pager. ** If memory-management is enabled, also remove pPg from the global list ** of free pages. */ static void lruListRemove(PgHdr *pPg){ listRemove(&pPg->pPager->lru, &pPg->free, pPg); #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT if( !pPg->pPager->memDb ){ sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU)); listRemove(&sqlite3LruPageList, &pPg->gfree, pPg); sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU)); } #endif } /* ** This function is called just after the needSync flag has been cleared ** from all pages managed by pPager (usually because the journal file ** has just been synced). It updates the pPager->lru.pFirstSynced variable ** and, if memory-management is enabled, the sqlite3LruPageList.pFirstSynced ** variable also. */ static void lruListSetFirstSynced(Pager *pPager){ pPager->lru.pFirstSynced = pPager->lru.pFirst; #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT if( !pPager->memDb ){ PgHdr *p; sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU)); for(p=sqlite3LruPageList.pFirst; p && p->needSync; p=p->gfree.pNext); assert(p==pPager->lru.pFirstSynced || p==sqlite3LruPageList.pFirstSynced); sqlite3LruPageList.pFirstSynced = p; sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU)); } #endif } /* ** Return true if page *pPg has already been written to the statement ** journal (or statement snapshot has been created, if *pPg is part |
︙ | ︙ | |||
2360 2361 2362 2363 2364 2365 2366 | /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ *ppPager = pPager; #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT pPager->iInUseMM = 0; pPager->iInUseDB = 0; if( !memDb ){ #ifndef SQLITE_MUTEX_NOOP | | | 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 | /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ *ppPager = pPager; #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT pPager->iInUseMM = 0; pPager->iInUseDB = 0; if( !memDb ){ #ifndef SQLITE_MUTEX_NOOP sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM2); #endif sqlite3_mutex_enter(mutex); pPager->pNext = sqlite3PagerList; if( sqlite3PagerList ){ assert( sqlite3PagerList->pPrev==0 ); sqlite3PagerList->pPrev = pPager; } |
︙ | ︙ | |||
2747 2748 2749 2750 2751 2752 2753 | ** a hot journal may be left in the filesystem but no error is returned ** to the caller. */ int sqlite3PagerClose(Pager *pPager){ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT if( !MEMDB ){ #ifndef SQLITE_MUTEX_NOOP | | | 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 | ** a hot journal may be left in the filesystem but no error is returned ** to the caller. */ int sqlite3PagerClose(Pager *pPager){ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT if( !MEMDB ){ #ifndef SQLITE_MUTEX_NOOP sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM2); #endif sqlite3_mutex_enter(mutex); if( pPager->pPrev ){ pPager->pPrev->pNext = pPager->pNext; }else{ sqlite3PagerList = pPager->pNext; } |
︙ | ︙ | |||
3274 3275 3276 3277 3278 3279 3280 | BusyHandler *savedBusy; /* Saved copy of the busy handler */ int rc = SQLITE_OK; /* Acquire the memory-management mutex */ #ifndef SQLITE_MUTEX_NOOP sqlite3_mutex *mutex; /* The MEM2 mutex */ | | | | | 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 | BusyHandler *savedBusy; /* Saved copy of the busy handler */ int rc = SQLITE_OK; /* Acquire the memory-management mutex */ #ifndef SQLITE_MUTEX_NOOP sqlite3_mutex *mutex; /* The MEM2 mutex */ mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM2); #endif sqlite3_mutex_enter(mutex); /* Signal all database connections that memory management wants ** to have access to the pagers. */ for(pPager=sqlite3PagerList; pPager; pPager=pPager->pNext){ pPager->iInUseMM = 1; } while( rc==SQLITE_OK && (nReq<0 || nReleased<nReq) ){ PgHdr *pPg; PgHdr *pRecycled; /* Try to find a page to recycle that does not require a sync(). If ** this is not possible, find one that does require a sync(). */ sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU)); pPg = sqlite3LruPageList.pFirstSynced; while( pPg && (pPg->needSync || pPg->pPager->iInUseDB) ){ pPg = pPg->gfree.pNext; } if( !pPg ){ pPg = sqlite3LruPageList.pFirst; while( pPg && pPg->pPager->iInUseDB ){ pPg = pPg->gfree.pNext; } } sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU)); /* If pPg==0, then the block above has failed to find a page to ** recycle. In this case return early - no further memory will ** be released. */ if( !pPg ) break; |
︙ | ︙ |
Changes to src/random.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** This file contains code to implement a pseudo-random number ** generator (PRNG) for SQLite. ** ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** This file contains code to implement a pseudo-random number ** generator (PRNG) for SQLite. ** ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. ** ** $Id: random.c,v 1.24 2008/06/18 17:09:10 danielk1977 Exp $ */ #include "sqliteInt.h" /* All threads share a single random number generator. ** This structure is the current state of the generator. */ |
︙ | ︙ | |||
88 89 90 91 92 93 94 | } /* ** Return N random bytes. */ void sqlite3_randomness(int N, void *pBuf){ unsigned char *zBuf = pBuf; | < < | < | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | } /* ** Return N random bytes. */ void sqlite3_randomness(int N, void *pBuf){ unsigned char *zBuf = pBuf; sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG); sqlite3_mutex_enter(mutex); while( N-- ){ *(zBuf++) = randomByte(); } sqlite3_mutex_leave(mutex); } |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.714 2008/06/18 17:09:10 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Include the configuration header output by 'configure' if we're using the ** autoconf-based build |
︙ | ︙ | |||
1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 | void *sqlite3ScratchMalloc(int); void sqlite3ScratchFree(void*); void *sqlite3PageMalloc(int); void sqlite3PageFree(void*); void sqlite3MemSetDefault(void); sqlite3_mutex_methods *sqlite3DefaultMutex(void); int sqlite3IsNaN(double); char *sqlite3MPrintf(sqlite3*,const char*, ...); char *sqlite3VMPrintf(sqlite3*,const char*, va_list); #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) void sqlite3DebugPrintf(const char*, ...); | > | 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 | void *sqlite3ScratchMalloc(int); void sqlite3ScratchFree(void*); void *sqlite3PageMalloc(int); void sqlite3PageFree(void*); void sqlite3MemSetDefault(void); sqlite3_mutex_methods *sqlite3DefaultMutex(void); sqlite3_mutex *sqlite3MutexAlloc(int); int sqlite3IsNaN(double); char *sqlite3MPrintf(sqlite3*,const char*, ...); char *sqlite3VMPrintf(sqlite3*,const char*, va_list); #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) void sqlite3DebugPrintf(const char*, ...); |
︙ | ︙ |
Changes to src/test3.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the btree.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the btree.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test3.c,v 1.98 2008/06/18 17:09:10 danielk1977 Exp $ */ #include "sqliteInt.h" #include "btreeInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
74 75 76 77 78 79 80 | return TCL_ERROR; } if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR; if( Tcl_GetInt(interp, argv[3], &flags) ) return TCL_ERROR; nRefSqlite3++; if( nRefSqlite3==1 ){ sDb.pVfs = sqlite3_vfs_find(0); | | | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | return TCL_ERROR; } if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR; if( Tcl_GetInt(interp, argv[3], &flags) ) return TCL_ERROR; nRefSqlite3++; if( nRefSqlite3==1 ){ sDb.pVfs = sqlite3_vfs_find(0); sDb.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); sqlite3_mutex_enter(sDb.mutex); } rc = sqlite3BtreeOpen(argv[1], &sDb, &pBt, flags, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; |
︙ | ︙ |
Changes to src/test_mutex.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* ** 2008 June 18 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* ** 2008 June 18 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** $Id: test_mutex.c,v 1.2 2008/06/18 17:09:10 danielk1977 Exp $ */ #include "tcl.h" #include "sqlite3.h" #include <stdlib.h> #include <assert.h> #include <string.h> |
︙ | ︙ | |||
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 | } for(ii=0; ii<8; ii++){ g.aCounter[ii] = 0; } return TCL_OK; } int Sqlitetest_mutex_Init(Tcl_Interp *interp){ static struct { char *zName; Tcl_ObjCmdProc *xProc; } aCmd[] = { { "sqlite3_shutdown", (Tcl_ObjCmdProc*)test_shutdown }, { "sqlite3_initialize", (Tcl_ObjCmdProc*)test_initialize }, { "install_mutex_counters", (Tcl_ObjCmdProc*)test_install_mutex_counters }, { "read_mutex_counters", (Tcl_ObjCmdProc*)test_read_mutex_counters }, { "clear_mutex_counters", (Tcl_ObjCmdProc*)test_clear_mutex_counters }, }; int i; for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); } memset(&g, 0, sizeof(g)); return SQLITE_OK; } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 297 298 299 300 301 302 303 304 305 306 | } for(ii=0; ii<8; ii++){ g.aCounter[ii] = 0; } return TCL_OK; } /* ** sqlite3_config OPTION */ static int test_config( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ struct ConfigOption { const char *zName; int iValue; } aOpt[] = { {"singlethread", SQLITE_CONFIG_SINGLETHREAD}, {"multithread", SQLITE_CONFIG_MULTITHREAD}, {"serialized", SQLITE_CONFIG_SERIALIZED}, {0, 0} }; int s = sizeof(struct ConfigOption); int i; int rc; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, ""); return TCL_ERROR; } if( Tcl_GetIndexFromObjStruct(interp, objv[1], aOpt, s, "flag", 0, &i) ){ return TCL_ERROR; } rc = sqlite3_config(aOpt[i].iValue); Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE); return TCL_OK; } int Sqlitetest_mutex_Init(Tcl_Interp *interp){ static struct { char *zName; Tcl_ObjCmdProc *xProc; } aCmd[] = { { "sqlite3_shutdown", (Tcl_ObjCmdProc*)test_shutdown }, { "sqlite3_initialize", (Tcl_ObjCmdProc*)test_initialize }, { "sqlite3_config", (Tcl_ObjCmdProc*)test_config }, { "install_mutex_counters", (Tcl_ObjCmdProc*)test_install_mutex_counters }, { "read_mutex_counters", (Tcl_ObjCmdProc*)test_read_mutex_counters }, { "clear_mutex_counters", (Tcl_ObjCmdProc*)test_clear_mutex_counters }, }; int i; for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); } memset(&g, 0, sizeof(g)); return SQLITE_OK; } |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code use to implement APIs that are part of the ** VDBE. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code use to implement APIs that are part of the ** VDBE. ** ** $Id: vdbeapi.c,v 1.133 2008/06/18 17:09:10 danielk1977 Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* ** The following structure contains pointers to the end points of a |
︙ | ︙ | |||
64 65 66 67 68 69 70 | /* ** Add vdbe p to the end of the statement lru list. It is assumed that ** p is not already part of the list when this is called. The lru list ** is protected by the SQLITE_MUTEX_STATIC_LRU mutex. */ static void stmtLruAdd(Vdbe *p){ | | | | | 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 | /* ** Add vdbe p to the end of the statement lru list. It is assumed that ** p is not already part of the list when this is called. The lru list ** is protected by the SQLITE_MUTEX_STATIC_LRU mutex. */ static void stmtLruAdd(Vdbe *p){ sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); if( p->pLruPrev || p->pLruNext || sqlite3LruStatements.pFirst==p ){ sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); return; } assert( stmtLruCheck() ); if( !sqlite3LruStatements.pFirst ){ assert( !sqlite3LruStatements.pLast ); sqlite3LruStatements.pFirst = p; sqlite3LruStatements.pLast = p; }else{ assert( !sqlite3LruStatements.pLast->pLruNext ); p->pLruPrev = sqlite3LruStatements.pLast; sqlite3LruStatements.pLast->pLruNext = p; sqlite3LruStatements.pLast = p; } assert( stmtLruCheck() ); sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); } /* ** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is already held, remove ** statement p from the least-recently-used statement list. If the ** statement is not currently part of the list, this call is a no-op. */ |
︙ | ︙ | |||
119 120 121 122 123 124 125 | /* ** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is not held, remove ** statement p from the least-recently-used statement list. If the ** statement is not currently part of the list, this call is a no-op. */ static void stmtLruRemove(Vdbe *p){ | | | | | | 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 | /* ** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is not held, remove ** statement p from the least-recently-used statement list. If the ** statement is not currently part of the list, this call is a no-op. */ static void stmtLruRemove(Vdbe *p){ sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); stmtLruRemoveNomutex(p); sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); } /* ** Try to release n bytes of memory by freeing buffers associated ** with the memory registers of currently unused vdbes. */ int sqlite3VdbeReleaseMemory(int n){ Vdbe *p; Vdbe *pNext; int nFree = 0; sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); for(p=sqlite3LruStatements.pFirst; p && nFree<n; p=pNext){ pNext = p->pLruNext; /* For each statement handle in the lru list, attempt to obtain the ** associated database mutex. If it cannot be obtained, continue ** to the next statement handle. It is not possible to block on ** the database mutex - that could cause deadlock. */ if( SQLITE_OK==sqlite3_mutex_try(p->db->mutex) ){ nFree += sqlite3VdbeReleaseBuffers(p); stmtLruRemoveNomutex(p); sqlite3_mutex_leave(p->db->mutex); } } sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); return nFree; } /* ** Call sqlite3Reprepare() on the statement. Remove it from the ** lru list before doing so, as Reprepare() will free all the |
︙ | ︙ |
Changes to test/mutex1.test.
1 2 3 4 5 6 7 8 9 10 11 | # 2008 June 17 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # 2008 June 17 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # $Id: mutex1.test,v 1.2 2008/06/18 17:09:10 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl proc mutex_counters {varname} { upvar $varname var set var(total) 0 |
︙ | ︙ | |||
71 72 73 74 75 76 77 | } {SQLITE_OK} do_test mutex1-1.9 { mutex_counters counters list $counters(total) $counters(static_master) } {0 0} | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | } {SQLITE_OK} do_test mutex1-1.9 { mutex_counters counters list $counters(total) $counters(static_master) } {0 0} #------------------------------------------------------------------------- # Tests mutex1-2.* test the three thread-safety related modes that # can be selected using sqlite3_config: # # * Serialized mode, # * Multi-threaded mode, # * Single-threaded mode. # foreach {mode mutexes} { singlethread {} multithread {fast static_master static_mem static_prng} serialized {fast recursive static_master static_mem static_prng} } { do_test mutex1.2.$mode.1 { catch {db close} sqlite3_shutdown sqlite3_config $mode } SQLITE_OK do_test mutex1.2.$mode.2 { clear_mutex_counters sqlite3 db test.db catchsql { CREATE TABLE abc(a, b, c) } db eval { INSERT INTO abc VALUES(1, 2, 3); } } {} do_test mutex1.2.$mode.3 { mutex_counters counters set res [list] foreach {key value} [array get counters] { if {$key ne "total" && $value > 0} { lappend res $key } } lsort $res } $mutexes } do_test mutex1-X { db close sqlite3_shutdown clear_mutex_counters install_mutex_counters 0 } {SQLITE_OK} finish_test |
Added test/mutex2.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 | # 2007 March 26 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # This file runs some other test files after calling sqlite3_config to # set the thread-safety mode to SQLITE_CONFIG_SINGLETHREAD and # SQLITE_CONFIG_MULTITHREAD (instead of the default SQLITE_CONFIG_SERIALIZED). # # $Id: mutex2.test,v 1.1 2008/06/18 17:09:10 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable {!pager_pragmas} { finish_test return } rename finish_test really_finish_test2 proc finish_test {} {} set ISQUICK 1 rename do_test really_do_test proc do_test {args} { set sc [concat really_do_test "mutex2-${::thread_mode}.[lindex $args 0]" \ [lrange $args 1 end]] eval $sc } foreach ::thread_mode {singlethread multithread} { do_test mutex2-$::thread_mode.0 { catch {db close} sqlite3_shutdown sqlite3_config $::thread_mode } SQLITE_OK source $testdir/delete.test source $testdir/delete2.test source $testdir/insert.test source $testdir/rollback.test source $testdir/select1.test source $testdir/select2.test source $testdir/trans.test source $testdir/update.test source $testdir/vacuum.test source $testdir/types.test source $testdir/types2.test source $testdir/types3.test #source $testdir/malloc.test #source $testdir/ioerr.test } do_test mutex2-X { catch {db close} sqlite3_shutdown sqlite3_config serialized } SQLITE_OK rename finish_test "" rename really_finish_test2 finish_test rename do_test "" rename really_do_test do_test finish_test |
Changes to test/quick.test.
1 2 3 4 5 6 7 8 | # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file runs all tests. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file runs all tests. # # $Id: quick.test,v 1.79 2008/06/18 17:09:10 danielk1977 Exp $ proc lshift {lvar} { upvar $lvar l set ret [lindex $l 0] set l [lrange $l 1 end] return $ret } |
︙ | ︙ | |||
60 61 62 63 64 65 66 67 68 69 70 71 72 73 | malloc.test malloc2.test malloc3.test malloc4.test memleak.test misc7.test misuse.test onefile.test quick.test soak.test speed1.test speed1p.test speed2.test speed3.test | > | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | malloc.test malloc2.test malloc3.test malloc4.test memleak.test misc7.test misuse.test mutex2.test onefile.test quick.test soak.test speed1.test speed1p.test speed2.test speed3.test |
︙ | ︙ |
Changes to test/veryquick.test.
1 2 3 4 5 6 7 8 | # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file runs all tests. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file runs all tests. # # $Id: veryquick.test,v 1.4 2008/06/18 17:09:10 danielk1977 Exp $ proc lshift {lvar} { upvar $lvar l set ret [lindex $l 0] set l [lrange $l 1 end] return $ret } |
︙ | ︙ | |||
82 83 84 85 86 87 88 89 90 91 92 93 94 95 | mallocD.test mallocE.test mallocF.test mallocG.test memleak.test misc7.test misuse.test onefile.test quick.test soak.test speed1.test speed1p.test speed2.test speed3.test | > | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | mallocD.test mallocE.test mallocF.test mallocG.test memleak.test misc7.test misuse.test mutex2.test onefile.test quick.test soak.test speed1.test speed1p.test speed2.test speed3.test |
︙ | ︙ |