Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Continuing progress on the new memory allocation subsystem. Added the sqlite3_mem_methods structure for defining new memory allocators at run-time. (CVS 5219) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
f00305f4cd2f487f660f34a21c1c24a0 |
User & Date: | drh 2008-06-14 16:56:22.000 |
Context
2008-06-15
| ||
02:51 | Continuing work on the new memory allocation subsystem. Added routines for temporary memory allocation. Right the btree balance mechanism to only do one temporary allocation at a time. (CVS 5220) (check-in: 65fe7b62cf user: drh tags: trunk) | |
2008-06-14
| ||
16:56 | Continuing progress on the new memory allocation subsystem. Added the sqlite3_mem_methods structure for defining new memory allocators at run-time. (CVS 5219) (check-in: f00305f4cd user: drh tags: trunk) | |
2008-06-13
| ||
18:24 | Progress toward implementation of sqlite3_config() and a rework of the mutex and memory allocation subsystems. This is an incremental check-in. (CVS 5218) (check-in: a03c5af115 user: drh tags: trunk) | |
Changes
Changes to src/global.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 definitions of global variables and contants. ** | | | 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 definitions of global variables and contants. ** ** $Id: global.c,v 1.2 2008/06/14 16:56:22 drh Exp $ */ #include "sqliteInt.h" /* An array to map all upper-case characters into their corresponding ** lower-case character. ** |
︙ | ︙ | |||
62 63 64 65 66 67 68 | #endif }; /* ** The following singleton contains the global configuration for ** the SQLite library. */ | | | 62 63 64 65 66 67 68 69 | #endif }; /* ** The following singleton contains the global configuration for ** the SQLite library. */ struct Sqlite3Config sqlite3Config = { 1, 1, 1, }; |
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.444 2008/06/14 16:56:22 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #ifdef SQLITE_ENABLE_FTS3 # include "fts3.h" #endif |
︙ | ︙ | |||
99 100 101 102 103 104 105 106 107 108 109 110 111 112 | ** Undo the effects of sqlite3_initialize(). Must not be called while ** there are outstanding database connections or memory allocations or ** while any part of SQLite is otherwise in use in any thread. This ** routine is not threadsafe. Not by a long shot. */ int sqlite3_shutdown(void){ sqlite3_os_end(); sqlite3_mutex_end(); sqlite3FullInit = 0; sqlite3IsInit = 0; return SQLITE_OK; } /* | > | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | ** Undo the effects of sqlite3_initialize(). Must not be called while ** there are outstanding database connections or memory allocations or ** while any part of SQLite is otherwise in use in any thread. This ** routine is not threadsafe. Not by a long shot. */ int sqlite3_shutdown(void){ sqlite3_os_end(); sqlite3MallocEnd(); sqlite3_mutex_end(); sqlite3FullInit = 0; sqlite3IsInit = 0; return SQLITE_OK; } /* |
︙ | ︙ | |||
145 146 147 148 149 150 151 | /* Enable all mutexing */ sqlite3Config.bCoreMutex = 1; sqlite3Config.bFullMutex = 1; break; } case SQLITE_CONFIG_MALLOC: { /* Specify an alternative malloc implementation */ | | < < < < | | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | /* Enable all mutexing */ sqlite3Config.bCoreMutex = 1; sqlite3Config.bFullMutex = 1; break; } case SQLITE_CONFIG_MALLOC: { /* Specify an alternative malloc implementation */ sqlite3Config.m = *va_arg(ap, sqlite3_mem_methods*); break; } case SQLITE_CONFIG_MEMSTATUS: { /* Enable or disable the malloc status collection */ sqlite3Config.bMemstat = va_arg(ap, int); break; } default: { rc = SQLITE_ERROR; break; |
︙ | ︙ |
Changes to src/malloc.c.
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. ** ************************************************************************* ** Memory allocation functions used throughout sqlite. ** | > < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /* ** 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. ** ************************************************************************* ** ** Memory allocation functions used throughout sqlite. ** ** $Id: malloc.c,v 1.16 2008/06/14 16:56:22 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> /* ** This routine runs when the memory allocator sees that the |
︙ | ︙ | |||
63 64 65 66 67 68 69 70 71 72 73 | nRet += sqlite3PagerReleaseMemory(n-nRet); return nRet; #else return SQLITE_OK; #endif } /* ** Allocate and zero memory. */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | 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 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 | nRet += sqlite3PagerReleaseMemory(n-nRet); return nRet; #else return SQLITE_OK; #endif } /* ** State information local to the memory allocation subsystem. */ static struct { sqlite3_mutex *mutex; /* Mutex to serialize access */ /* ** The alarm callback and its arguments. The mem0.mutex lock will ** be held while the callback is running. Recursive calls into ** the memory subsystem are allowed, but no new callbacks will be ** issued. The alarmBusy variable is set to prevent recursive ** callbacks. */ sqlite3_int64 alarmThreshold; void (*alarmCallback)(void*, sqlite3_int64,int); void *alarmArg; int alarmBusy; /* ** Performance statistics */ sqlite3_int64 nowUsed; /* Main memory currently in use */ sqlite3_int64 mxUsed; /* Highwater mark for nowUsed */ int mxReq; /* maximum request size for main or page-cache mem */ } mem0; /* ** Initialize the memory allocation subsystem. */ int sqlite3MallocInit(void){ if( sqlite3Config.m.xMalloc==0 ){ sqlite3MemSetDefault(); } memset(&mem0, 0, sizeof(mem0)); if( sqlite3Config.bMemstat && sqlite3Config.bCoreMutex ){ mem0.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); } return sqlite3Config.m.xInit(sqlite3Config.m.pAppData); } /* ** Deinitialize the memory allocation subsystem. */ void sqlite3MallocEnd(void){ sqlite3Config.m.xShutdown(sqlite3Config.m.pAppData); } /* ** Return the amount of memory currently checked out. */ sqlite3_int64 sqlite3_memory_used(void){ sqlite3_int64 n; sqlite3_mutex_enter(mem0.mutex); n = mem0.nowUsed; sqlite3_mutex_leave(mem0.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_int64 sqlite3_memory_highwater(int resetFlag){ sqlite3_int64 n; sqlite3_mutex_enter(mem0.mutex); n = mem0.mxUsed; if( resetFlag ){ mem0.mxUsed = mem0.nowUsed; } sqlite3_mutex_leave(mem0.mutex); return n; } /* ** Change the alarm callback */ int sqlite3_memory_alarm( void(*xCallback)(void *pArg, sqlite3_int64 used,int N), void *pArg, sqlite3_int64 iThreshold ){ sqlite3_mutex_enter(mem0.mutex); mem0.alarmCallback = xCallback; mem0.alarmArg = pArg; mem0.alarmThreshold = iThreshold; sqlite3_mutex_leave(mem0.mutex); return SQLITE_OK; } /* ** Trigger the alarm */ static void sqlite3MallocAlarm(int nByte){ void (*xCallback)(void*,sqlite3_int64,int); sqlite3_int64 nowUsed; void *pArg; if( mem0.alarmCallback==0 || mem0.alarmBusy ) return; mem0.alarmBusy = 1; xCallback = mem0.alarmCallback; nowUsed = mem0.nowUsed; pArg = mem0.alarmArg; sqlite3_mutex_leave(mem0.mutex); xCallback(pArg, nowUsed, nByte); sqlite3_mutex_enter(mem0.mutex); mem0.alarmBusy = 0; } /* ** Allocate memory. This routine is like sqlite3_malloc() except that it ** assumes the memory subsystem has already been initialized. */ void *sqlite3Malloc(int n){ void *p; int nFull; if( n<=0 ){ return 0; }else if( sqlite3Config.bMemstat ){ nFull = sqlite3Config.m.xRoundup(n); sqlite3_mutex_enter(mem0.mutex); if( n>mem0.mxReq ) mem0.mxReq = n; if( mem0.alarmCallback!=0 && mem0.nowUsed+nFull>=mem0.alarmThreshold ){ sqlite3MallocAlarm(nFull); } if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){ p = 0; }else{ p = sqlite3Config.m.xMalloc(nFull); if( p==0 ){ sqlite3MallocAlarm(nFull); p = malloc(nFull); } } if( p ){ mem0.nowUsed += nFull; if( mem0.nowUsed>mem0.mxUsed ){ mem0.mxUsed = mem0.nowUsed; } } sqlite3_mutex_leave(mem0.mutex); }else{ p = sqlite3Config.m.xMalloc(n); } return p; } /* ** This version of the memory allocation is for use by the application. ** First make sure the memory subsystem is initialized, then do the ** allocation. */ void *sqlite3_malloc(int n){ #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif return sqlite3Malloc(n); } /* ** Return the size of a memory allocation previously obtained from ** sqlite3Malloc() or sqlite3_malloc(). */ int sqlite3MallocSize(void *p){ return sqlite3Config.m.xSize(p); } /* ** Free memory previously obtained from sqlite3Malloc(). */ void sqlite3_free(void *p){ if( p==0 ) return; if( sqlite3Config.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); mem0.nowUsed -= sqlite3MallocSize(p); sqlite3Config.m.xFree(p); sqlite3_mutex_leave(mem0.mutex); }else{ sqlite3Config.m.xFree(p); } } /* ** Change the size of an existing memory allocation */ void *sqlite3Realloc(void *pOld, int nBytes){ int nOld, nNew; void *pNew; if( pOld==0 ){ return sqlite3Malloc(nBytes); } if( nBytes<=0 ){ sqlite3_free(pOld); return 0; } nOld = sqlite3MallocSize(pOld); if( sqlite3Config.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); if( nBytes>mem0.mxReq ) mem0.mxReq = nBytes; nNew = sqlite3Config.m.xRoundup(nBytes); if( nOld==nNew ){ pNew = pOld; }else{ if( mem0.nowUsed+nNew-nOld>=mem0.alarmThreshold ){ sqlite3MallocAlarm(nNew-nOld); } if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){ pNew = 0; }else{ pNew = sqlite3Config.m.xRealloc(pOld, nNew); if( pNew==0 ){ sqlite3MallocAlarm(nBytes); pNew = sqlite3Config.m.xRealloc(pOld, nNew); } } if( pNew ){ mem0.nowUsed += nNew-nOld; if( mem0.nowUsed>mem0.mxUsed ){ mem0.mxUsed = mem0.nowUsed; } } } sqlite3_mutex_leave(mem0.mutex); }else{ pNew = sqlite3Config.m.xRealloc(pOld, nBytes); } return pNew; } /* ** The public interface to sqlite3Realloc. Make sure that the memory ** subsystem is initialized prior to invoking sqliteRealloc. */ void *sqlite3_realloc(void *pOld, int n){ #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif return sqlite3Realloc(pOld, n); } /* ** Allocate and zero memory. */ void *sqlite3MallocZero(int n){ void *p = sqlite3Malloc(n); if( p ){ memset(p, 0, n); } return p; } /* ** Allocate and zero memory. If the allocation fails, make ** the mallocFailed flag in the connection pointer. */ void *sqlite3DbMallocZero(sqlite3 *db, int n){ void *p = sqlite3DbMallocRaw(db, n); if( p ){ memset(p, 0, n); } return p; } /* ** Allocate and zero memory. If the allocation fails, make ** the mallocFailed flag in the connection pointer. */ void *sqlite3DbMallocRaw(sqlite3 *db, int n){ void *p = 0; if( !db || db->mallocFailed==0 ){ p = sqlite3Malloc(n); if( !p && db ){ db->mallocFailed = 1; } } return p; } |
︙ | ︙ |
Changes to src/mem1.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2007 August 14 ** ** 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 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 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 | /* ** 2007 August 14 ** ** 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 contains low-level memory allocation drivers for when ** SQLite will use the standard C-library malloc/realloc/free interface ** to obtain the memory it needs. ** ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. ** ** $Id: mem1.c,v 1.19 2008/06/14 16:56:22 drh Exp $ */ #include "sqliteInt.h" /* ** This version of the memory allocator is the default. It is ** used when no other memory allocator is specified using compile-time ** macros. */ #ifdef SQLITE_SYSTEM_MALLOC /* ** Like malloc(), but remember the size of the allocation ** so that we can find it later using sqlite3MemSize(). ** ** For this low-level routine, we are guaranteed that nByte>0 because ** cases of nByte<=0 will be intercepted and dealt with by higher level ** routines. */ static void *sqlite3MemMalloc(int nByte){ sqlite3_int64 *p; assert( nByte>0 ); nByte = (nByte+7)&~7; p = malloc( nByte+8 ); p[0] = nByte; return (void*)&p[1]; } /* ** Like free() but works for allocations obtained from sqlite3MemMalloc() ** or sqlite3MemRealloc(). ** ** For this low-level routine, we already know that pPrior!=0 since ** cases where pPrior==0 will have been intecepted and dealt with ** by higher-level routines. */ static void sqlite3MemFree(void *pPrior){ assert( pPrior!=0 ); sqlite3_int64 *p = (sqlite3_int64*)pPrior; p--; free(p); } /* ** Like realloc(). Resize an allocation previously obtained from ** sqlite3MemMalloc(). ** ** For this low-level interface, we know that pPrior!=0. Cases where ** pPrior==0 while have been intercepted by higher-level routine and ** redirected to xMalloc. Similarly, we know that nByte>0 becauses ** cases where nByte<=0 will have been intercepted by higher-level ** routines and redirected to xFree. */ static void *sqlite3MemRealloc(void *pPrior, int nByte){ sqlite3_int64 *p = (sqlite3_int64*)pPrior; assert( pPrior!=0 && nByte>0 ); nByte = (nByte+7)&~7; p = (sqlite3_int64*)pPrior; p--; p = realloc(p, nByte+8 ); if( p ){ p[0] = nByte; p++; } return (void*)p; } /* ** Report the allocated size of a prior return from xMalloc() ** or xRealloc(). */ static int sqlite3MemSize(void *pPrior){ sqlite3_int64 *p; if( pPrior==0 ) return 0; p = (sqlite3_int64*)pPrior; p--; return p[0]; } /* ** Round up a request size to the next valid allocation size. */ static int sqlite3MemRoundup(int n){ return (n+7) & ~7; } /* ** Initialize this module. */ static int sqlite3MemInit(void *NotUsed){ return SQLITE_OK; } /* ** Deinitialize this module. */ static void sqlite3MemShutdown(void *NotUsed){ return; } /* ** This routine is the only routine in this file with external linkage. ** ** Populate the low-level memory allocation function pointers in ** sqlite3Config.m with pointers to the routines in this file. */ void sqlite3MemSetDefault(void){ static const sqlite3_mem_methods defaultMethods = { sqlite3MemMalloc, sqlite3MemFree, sqlite3MemRealloc, sqlite3MemSize, sqlite3MemRoundup, sqlite3MemInit, sqlite3MemShutdown, 0 }; sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); } #endif /* SQLITE_SYSTEM_MALLOC */ |
Changes to src/mem2.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2007 August 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. ** ************************************************************************* | > | > > | > > > > | | 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 | /* ** 2007 August 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. ** ************************************************************************* ** ** This file contains low-level memory allocation drivers for when ** SQLite will use the standard C-library malloc/realloc/free interface ** 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.28 2008/06/14 16:56:22 drh Exp $ */ #include "sqliteInt.h" /* ** This version of the memory allocator is used only if the ** SQLITE_MEMDEBUG macro is defined */ |
︙ | ︙ | |||
70 71 72 73 74 75 76 | /* ** All of the static variables used by this module are collected ** into a single structure named "mem". This is to keep the ** static variables organized and to reduce namespace pollution ** when this module is combined with other in the amalgamation. */ static struct { | < < < < < < < < < < < | < < < < < < | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | /* ** All of the static variables used by this module are collected ** into a single structure named "mem". This is to keep the ** static variables organized and to reduce namespace pollution ** when this module is combined with other in the amalgamation. */ static struct { /* ** Mutex to control access to the memory allocation subsystem. */ sqlite3_mutex *mutex; /* ** Head and tail of a linked list of all outstanding allocations */ struct MemBlockHdr *pFirst; struct MemBlockHdr *pLast; /* |
︙ | ︙ | |||
127 128 129 130 131 132 133 | ** bytes. i==NCSIZE is the number of allocation attempts for ** sizes more than NCSIZE*8 bytes. */ int sizeCnt[NCSIZE]; } mem; | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | ** bytes. i==NCSIZE is the number of allocation attempts for ** sizes more than NCSIZE*8 bytes. */ int sizeCnt[NCSIZE]; } mem; /* ** Given an allocation, find the MemBlockHdr for that allocation. ** ** This routine checks the guards at either end of the allocation and ** if they are incorrect it asserts. */ static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){ |
︙ | ︙ | |||
227 228 229 230 231 232 233 | assert( (nReserve-2)<=p->iSize || pU8[nReserve-3]==0x65 ); return p; } /* ** Return the number of bytes currently allocated at address p. */ | | | | > > > > > > > > > > > > > > > > | < < | | | < < < | | | | | | | | < < < | < < < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < < < | | | < | < < < < | 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 | assert( (nReserve-2)<=p->iSize || pU8[nReserve-3]==0x65 ); return p; } /* ** Return the number of bytes currently allocated at address p. */ static int sqlite3MemSize(void *p){ struct MemBlockHdr *pHdr; if( !p ){ return 0; } pHdr = sqlite3MemsysGetHeader(p); return pHdr->iSize; } /* ** Initialize the memory allocation subsystem. */ static int sqlite3MemInit(void *NotUsed){ mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); return SQLITE_OK; } /* ** Deinitialize the memory allocation subsystem. */ static void sqlite3MemShutdown(void *NotUsed){ sqlite3_mutex_free(mem.mutex); mem.mutex = 0; } /* ** Round up a request size to the next valid allocation size. */ static int sqlite3MemRoundup(int n){ return (n+7) & ~7; } /* ** Allocate nByte bytes of memory. */ static void *sqlite3MemMalloc(int nByte){ struct MemBlockHdr *pHdr; void **pBt; char *z; int *pInt; void *p = 0; int totalSize; int nReserve; sqlite3_mutex_enter(mem.mutex); assert( mem.disallow==0 ); nReserve = (nByte+7)&~7; if( nReserve/8>NCSIZE-1 ){ mem.sizeCnt[NCSIZE-1]++; }else{ mem.sizeCnt[nReserve/8]++; } totalSize = nReserve + sizeof(*pHdr) + sizeof(int) + mem.nBacktrace*sizeof(void*) + mem.nTitle; p = malloc(totalSize); if( p ){ z = p; pBt = (void**)&z[mem.nTitle]; pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace]; pHdr->pNext = 0; pHdr->pPrev = mem.pLast; if( mem.pLast ){ mem.pLast->pNext = pHdr; }else{ mem.pFirst = pHdr; } mem.pLast = pHdr; pHdr->iForeGuard = FOREGUARD; pHdr->nBacktraceSlots = mem.nBacktrace; pHdr->nTitle = mem.nTitle; if( mem.nBacktrace ){ void *aAddr[40]; pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1; memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*)); if( mem.xBacktrace ){ mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]); } }else{ pHdr->nBacktrace = 0; } if( mem.nTitle ){ memcpy(z, mem.zTitle, mem.nTitle); } pHdr->iSize = nByte; pInt = (int*)&pHdr[1]; pInt[nReserve/sizeof(int)] = REARGUARD; memset(pInt, 0x65, nReserve); p = (void*)pInt; } sqlite3_mutex_leave(mem.mutex); return p; } /* ** Free memory. */ static void sqlite3MemFree(void *pPrior){ struct MemBlockHdr *pHdr; void **pBt; char *z; assert( mem.mutex!=0 ); pHdr = sqlite3MemsysGetHeader(pPrior); pBt = (void**)pHdr; pBt -= pHdr->nBacktraceSlots; sqlite3_mutex_enter(mem.mutex); if( pHdr->pPrev ){ assert( pHdr->pPrev->pNext==pHdr ); pHdr->pPrev->pNext = pHdr->pNext; }else{ assert( mem.pFirst==pHdr ); mem.pFirst = pHdr->pNext; } |
︙ | ︙ | |||
368 369 370 371 372 373 374 | ** ** For this debugging implementation, we *always* make a copy of the ** allocation into a new place in memory. In this way, if the ** higher level code is using pointer to the old allocation, it is ** much more likely to break and we are much more liking to find ** the error. */ | | < < < < < < < | | > > > > > > > > > > > > > > > > > > > | 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 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 | ** ** For this debugging implementation, we *always* make a copy of the ** allocation into a new place in memory. In this way, if the ** higher level code is using pointer to the old allocation, it is ** much more likely to break and we are much more liking to find ** the error. */ static void *sqlite3MemRealloc(void *pPrior, int nByte){ struct MemBlockHdr *pOldHdr; void *pNew; assert( mem.disallow==0 ); pOldHdr = sqlite3MemsysGetHeader(pPrior); pNew = sqlite3MemMalloc(nByte); if( pNew ){ memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize); if( nByte>pOldHdr->iSize ){ memset(&((char*)pNew)[pOldHdr->iSize], 0x2b, nByte - pOldHdr->iSize); } sqlite3MemFree(pPrior); } return pNew; } /* ** Populate the low-level memory allocation function pointers in ** sqlite3Config.m with pointers to the routines in this file. */ void sqlite3MemSetDefault(void){ static const sqlite3_mem_methods defaultMethods = { sqlite3MemMalloc, sqlite3MemFree, sqlite3MemRealloc, sqlite3MemSize, sqlite3MemRoundup, sqlite3MemInit, sqlite3MemShutdown, 0 }; sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); } /* ** Set the number of backtrace levels kept for each allocation. ** A value of zero turns of backtracing. The number is always rounded ** up to a multiple of 2. */ void sqlite3MemdebugBacktrace(int depth){ if( depth<0 ){ depth = 0; } |
︙ | ︙ | |||
412 413 414 415 416 417 418 | } /* ** Set the title string for subsequent allocations. */ void sqlite3MemdebugSettitle(const char *zTitle){ int n = strlen(zTitle) + 1; | | | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | } /* ** Set the title string for subsequent allocations. */ void sqlite3MemdebugSettitle(const char *zTitle){ int n = strlen(zTitle) + 1; sqlite3_mutex_enter(mem.mutex); if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1; memcpy(mem.zTitle, zTitle, n); mem.zTitle[n] = 0; mem.nTitle = (n+7)&~7; sqlite3_mutex_leave(mem.mutex); } |
︙ | ︙ | |||
470 471 472 473 474 475 476 | if( mem.sizeCnt[NCSIZE-1] ){ fprintf(out, " >%3d: %d\n", NCSIZE*8, mem.sizeCnt[NCSIZE-1]); } fclose(out); } /* | | | 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 | if( mem.sizeCnt[NCSIZE-1] ){ fprintf(out, " >%3d: %d\n", NCSIZE*8, mem.sizeCnt[NCSIZE-1]); } fclose(out); } /* ** Return the number of times sqlite3MemMalloc() has been called. */ int sqlite3MemdebugMallocCount(){ int i; int nTotal = 0; for(i=0; i<NCSIZE; i++){ nTotal += mem.sizeCnt[i]; } return nTotal; } #endif /* SQLITE_MEMDEBUG */ |
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 | ** 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.19 2008/06/14 16:56:23 drh Exp $ */ #include "sqliteInt.h" #ifdef SQLITE_MUTEX_NOOP_DEBUG /* ** In this implementation, mutexes do not provide any mutual exclusion. ** But the error checking is provided. This implementation is useful |
︙ | ︙ | |||
73 74 75 76 77 78 79 | return pNew; } /* ** This routine deallocates a previously allocated mutex. */ void sqlite3_mutex_free(sqlite3_mutex *p){ | | | | | | > | | | > | | | | > | 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 | return pNew; } /* ** This routine deallocates a previously allocated mutex. */ void sqlite3_mutex_free(sqlite3_mutex *p){ if( p==0 ) return; assert( p->cnt==0 ); assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); 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 *p){ if( p ){ assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); p->cnt++; } } int sqlite3_mutex_try(sqlite3_mutex *p){ if( p ){ assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); p->cnt++; } return SQLITE_OK; } /* ** The sqlite3_mutex_leave() 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 *p){ if( p ){ assert( sqlite3_mutex_held(p) ); p->cnt--; assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); } } /* ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are ** intended for use inside assert() statements. */ int sqlite3_mutex_held(sqlite3_mutex *p){ return p==0 || p->cnt>0; } int sqlite3_mutex_notheld(sqlite3_mutex *p){ return p==0 || p->cnt==0; } #endif /* SQLITE_MUTEX_NOOP_DEBUG */ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
26 27 28 29 30 31 32 | ** 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. ** | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ** 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.327 2008/06/14 16:56:23 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++. |
︙ | ︙ | |||
938 939 940 941 942 943 944 945 946 947 948 949 950 951 | ** ** When a configuration option is set, sqlite3_config() returns SQLITE_OK. ** If the option is unknown or SQLite is unable to set the option ** then this routine returns a non-zero [error code]. */ int sqlite3_config(int, ...); /* ** CAPI3REF: Configuration Options {F10160} ** ** These constants are the available integer configuration options that ** can be passed as the first argument to the [sqlite3_config()] interface. ** ** <dl> | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 | ** ** When a configuration option is set, sqlite3_config() returns SQLITE_OK. ** If the option is unknown or SQLite is unable to set the option ** then this routine returns a non-zero [error code]. */ int sqlite3_config(int, ...); /* ** CAPI3REF: Memory Allocation Routines {F10155} ** ** An instance of this object defines the interface between SQLite ** and low-level memory allocation routines. ** ** This object is used in only one place in the SQLite interface. ** A pointer to an instance of this object is the argument to ** [sqlite3_config] when the configuration option is ** [SQLITE_CONFIG_MALLOC]. By creating an instance of this object ** and passing it to [sqlite3_config] during configuration, an ** application can specify an alternative memory allocation subsystem ** for SQLite to use for all of its dynamic memory needs. ** ** Note that SQLite comes with a built-in memory allocator that is ** perfectly adequate for the overwhelming majority of applications ** and that this object is only useful to a tiny minority of applications ** with specialized memory allocation requirements. This object is ** also used during testing of SQLite in order to specify an alternative ** memory allocator that simulates memory out-of-memory conditions in ** order to verify that SQLite recovers gracefully from such ** conditions. ** ** The xMalloc, xFree, and xRealloc methods should work like the ** malloc(), free(), and realloc() functions from the standard library. ** ** xSize should return the allocated size of a memory allocation ** previously obtained from xMalloc or xRealloc. The allocated size ** is always at least as big as the requested size but may be larger. ** ** The xRoundup method returns what would be the allocated size of ** a memory allocation given a particular requested size. Most memory ** allocators round up memory allocations at least to the next multiple ** of 8. Some round up to a larger multiple or to a power of 2. ** ** The xInit method initializes the memory allocator. (For example, ** it might allocate any require mutexes or initialize internal data ** structures. The xShutdown method is invoked (indirectly) by ** [sqlite3_shutdown()] and should deallocate any resources acquired ** by xInit. The pAppData pointer is used as the only parameter to ** xInit and xShutdown. */ typedef struct sqlite3_mem_methods sqlite3_mem_methods; struct sqlite3_mem_methods { void *(*xMalloc)(int); /* Memory allocation function */ void (*xFree)(void*); /* Free a prior allocation */ void *(*xRealloc)(void*,int); /* Resize an allocation */ int (*xSize)(void*); /* Return the size of an allocation */ int (*xRoundup)(int); /* Round up request size to allocation size */ int (*xInit)(void*); /* Initialize the memory allocator */ void (*xShutdown)(void*); /* Deinitialize the memory allocator */ void *pAppData; /* Argument to xInit() and xShutdown() */ }; /* ** CAPI3REF: Configuration Options {F10160} ** ** These constants are the available integer configuration options that ** can be passed as the first argument to the [sqlite3_config()] interface. ** ** <dl> |
︙ | ︙ | |||
969 970 971 972 973 974 975 | ** In this mode (which is the default when SQLite is compiled with ** SQLITE_THREADSAFE=1) the SQLite library will itself serialize access ** to [database connections] and [prepared statements] so that the ** application is free to use the same [database connection] or the ** same [prepared statement] in different threads at the same time.</dd> ** ** <dt>SQLITE_CONFIG_MALLOC</dt> | | < < < | | < | | | | | 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 | ** In this mode (which is the default when SQLite is compiled with ** SQLITE_THREADSAFE=1) the SQLite library will itself serialize access ** to [database connections] and [prepared statements] so that the ** application is free to use the same [database connection] or the ** same [prepared statement] in different threads at the same time.</dd> ** ** <dt>SQLITE_CONFIG_MALLOC</dt> ** <dd>This option takes a single argument which is a pointer to an ** instance of the [sqlite3_mem_methods] structure. The argument specifics ** alternative low-level memory allocation routines to be used in place ** the memory allocation routines built into SQLite.</dd> ** ** <dt>SQLITE_CONFIG_MEMSTATUS</dt> ** <dd>This option takes single boolean argument which enables or disables ** the collection of memory allocation statistics. When disabled, the ** following SQLite interfaces become non-operational: ** <ul> ** <li> [sqlite3_memory_used()] ** <li> [sqlite3_memory_highwater()] ** <li> [sqlite3_soft_heap_limit()] ** <li> sqlite3_memory_status() ** </ul> ** </dd> ** </dl> */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ #define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ #define SQLITE_CONFIG_MEMSTATUS 5 /* boolean */ /* These options are to be added later. Currently unused and undocumented. */ #define SQLITE_CONFIG_HEAP 6 /* void*, int64, min, max, tmp */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes {F12200} |
︙ | ︙ |
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.709 2008/06/14 16:56:23 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Include the configuration header output by 'configure' if we're using the ** autoconf-based build |
︙ | ︙ | |||
1731 1732 1733 1734 1735 1736 1737 | int rc; /* Result code stored here */ } InitData; /* ** Structure containing global configuration data for the SQLite library. */ struct Sqlite3Config { | | < | | | < < < | 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 | int rc; /* Result code stored here */ } InitData; /* ** Structure containing global configuration data for the SQLite library. */ struct Sqlite3Config { int bMemstat; /* True to enable memory status */ int bCoreMutex; /* True to enable core mutexing */ int bFullMutex; /* True to enable full mutexing */ sqlite3_mem_methods m; /* Low-level memory allocation interface */ void *pHeap; /* Heap storage space */ sqlite3_int64 nHeap; /* Size of pHeap[] */ int mnReq, mxReq; /* Min and max memory request sizes */ int nTemp; /* Part of pHeap for temporary allos */ }; /* ** Assuming zIn points to the first byte of a UTF-8 character, ** advance zIn to point to the first byte of the next UTF-8 character. */ #define SQLITE_SKIP_UTF8(zIn) { \ |
︙ | ︙ | |||
1778 1779 1780 1781 1782 1783 1784 | ** Internal function prototypes */ int sqlite3StrICmp(const char *, const char *); int sqlite3StrNICmp(const char *, const char *, int); int sqlite3IsNumber(const char*, int*, u8); int sqlite3MallocInit(void); | > | > | | > > | 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 | ** Internal function prototypes */ int sqlite3StrICmp(const char *, const char *); int sqlite3StrNICmp(const char *, const char *, int); int sqlite3IsNumber(const char*, int*, u8); int sqlite3MallocInit(void); void sqlite3MallocEnd(void); void *sqlite3Malloc(int); void *sqlite3MallocZero(int); void *sqlite3DbMallocZero(sqlite3*, int); void *sqlite3DbMallocRaw(sqlite3*, int); char *sqlite3StrDup(const char*); char *sqlite3StrNDup(const char*, int); char *sqlite3DbStrDup(sqlite3*,const char*); char *sqlite3DbStrNDup(sqlite3*,const char*, int); void *sqlite3Realloc(void*, int); void *sqlite3DbReallocOrFree(sqlite3 *, void *, int); void *sqlite3DbRealloc(sqlite3 *, void *, int); int sqlite3MallocSize(void *); void sqlite3MemSetDefault(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*, ...); |
︙ | ︙ |