1 /* 2 ** 2007 October 14 3 ** 4 ** The author disclaims copyright to this source code. In place of 5 ** a legal notice, here is a blessing: 6 ** 7 ** May you do good and not evil. 8 ** May you find forgiveness for yourself and forgive others. 9 ** May you share freely, never taking more than you give. 10 ** 11 ************************************************************************* 12 ** This file contains the C functions that implement a memory 13 ** allocation subsystem for use by SQLite. 14 ** 15 ** This version of the memory allocation subsystem omits all 16 ** use of malloc(). All dynamically allocatable memory is 17 ** contained in a static array, mem.aPool[]. The size of this 18 ** fixed memory pool is SQLITE_POW2_MEMORY_SIZE bytes. 19 ** 20 ** This version of the memory allocation subsystem is used if 21 ** and only if SQLITE_POW2_MEMORY_SIZE is defined. 22 ** 23 ** $Id: mem5.c,v 1.4 2008/02/19 15:15:16 drh Exp $ 24 */ 25 #include "sqliteInt.h" 26 27 /* 28 ** This version of the memory allocator is used only when 29 ** SQLITE_POW2_MEMORY_SIZE is defined. 30 */ 31 #ifdef SQLITE_POW2_MEMORY_SIZE 32 33 /* 34 ** Log2 of the minimum size of an allocation. For example, if 35 ** 4 then all allocations will be rounded up to at least 16 bytes. 36 ** If 5 then all allocations will be rounded up to at least 32 bytes. 37 */ 38 #ifndef SQLITE_POW2_LOGMIN 39 # define SQLITE_POW2_LOGMIN 6 40 #endif 41 #define POW2_MIN (1<<SQLITE_POW2_LOGMIN) 42 43 /* 44 ** Log2 of the maximum size of an allocation. 45 */ 46 #ifndef SQLITE_POW2_LOGMAX 47 # define SQLITE_POW2_LOGMAX 18 48 #endif 49 #define POW2_MAX (((unsigned int)1)<<SQLITE_POW2_LOGMAX) 50 51 /* 52 ** Number of distinct allocation sizes. 53 */ 54 #define NSIZE (SQLITE_POW2_LOGMAX - SQLITE_POW2_LOGMIN + 1) 55 56 /* 57 ** A minimum allocation is an instance of the following structure. 58 ** Larger allocations are an array of these structures where the 59 ** size of the array is a power of 2. 60 */ 61 typedef struct Mem5Block Mem5Block; 62 struct Mem5Block { 63 union { 64 char aData[POW2_MIN]; 65 struct { 66 int next; /* Index in mem.aPool[] of next free chunk */ 67 int prev; /* Index in mem.aPool[] of previous free chunk */ 68 } list; 69 } u; 70 }; 71 72 /* 73 ** Number of blocks of memory available for allocation. 74 */ 75 #define NBLOCK (SQLITE_POW2_MEMORY_SIZE/POW2_MIN) 76 77 /* 78 ** The size in blocks of an POW2_MAX allocation 79 */ 80 #define SZ_MAX (1<<(NSIZE-1)) 81 82 /* 83 ** Masks used for mem.aCtrl[] elements. 84 */ 85 #define CTRL_LOGSIZE 0x1f /* Log2 Size of this block relative to POW2_MIN */ 86 #define CTRL_FREE 0x20 /* True if not checked out */ 87 88 /* 89 ** All of the static variables used by this module are collected 90 ** into a single structure named "mem". This is to keep the 91 ** static variables organized and to reduce namespace pollution 92 ** when this module is combined with other in the amalgamation. 93 */ 94 static struct { 95 /* 96 ** The alarm callback and its arguments. The mem.mutex lock will 97 ** be held while the callback is running. Recursive calls into 98 ** the memory subsystem are allowed, but no new callbacks will be 99 ** issued. The alarmBusy variable is set to prevent recursive 100 ** callbacks. 101 */ 102 sqlite3_int64 alarmThreshold; 103 void (*alarmCallback)(void*, sqlite3_int64,int); 104 void *alarmArg; 105 int alarmBusy; 106 107 /* 108 ** Mutex to control access to the memory allocation subsystem. 109 */ 110 sqlite3_mutex *mutex; 111 112 /* 113 ** Performance statistics 114 */ 115 u64 nAlloc; /* Total number of calls to malloc */ 116 u64 totalAlloc; /* Total of all malloc calls - includes internal frag */ 117 u64 totalExcess; /* Total internal fragmentation */ 118 u32 currentOut; /* Current checkout, including internal fragmentation */ 119 u32 currentCount; /* Current number of distinct checkouts */ 120 u32 maxOut; /* Maximum instantaneous currentOut */ 121 u32 maxCount; /* Maximum instantaneous currentCount */ 122 u32 maxRequest; /* Largest allocation (exclusive of internal frag) */ 123 124 /* 125 ** Lists of free blocks of various sizes. 126 */ 127 int aiFreelist[NSIZE]; 128 129 /* 130 ** Space for tracking which blocks are checked out and the size 131 ** of each block. One byte per block. 132 */ 133 u8 aCtrl[NBLOCK]; 134 135 /* 136 ** Memory available for allocation 137 */ 138 Mem5Block aPool[NBLOCK]; 139 } mem; 140 141 /* 142 ** Unlink the chunk at mem.aPool[i] from list it is currently 143 ** on. It should be found on mem.aiFreelist[iLogsize]. 144 */ 145 static void memsys5Unlink(int i, int iLogsize){ 146 int next, prev; 147 assert( i>=0 && i<NBLOCK ); 148 assert( iLogsize>=0 && iLogsize<NSIZE ); 149 assert( (mem.aCtrl[i] & CTRL_LOGSIZE)==iLogsize ); 150 assert( sqlite3_mutex_held(mem.mutex) ); 151 152 next = mem.aPool[i].u.list.next; 153 prev = mem.aPool[i].u.list.prev; 154 if( prev<0 ){ 155 mem.aiFreelist[iLogsize] = next; 156 }else{ 157 mem.aPool[prev].u.list.next = next; 158 } 159 if( next>=0 ){ 160 mem.aPool[next].u.list.prev = prev; 161 } 162 } 163 164 /* 165 ** Link the chunk at mem.aPool[i] so that is on the iLogsize 166 ** free list. 167 */ 168 static void memsys5Link(int i, int iLogsize){ 169 int x; 170 assert( sqlite3_mutex_held(mem.mutex) ); 171 assert( i>=0 && i<NBLOCK ); 172 assert( iLogsize>=0 && iLogsize<NSIZE ); 173 assert( (mem.aCtrl[i] & CTRL_LOGSIZE)==iLogsize ); 174 175 mem.aPool[i].u.list.next = x = mem.aiFreelist[iLogsize]; 176 mem.aPool[i].u.list.prev = -1; 177 if( x>=0 ){ 178 assert( x<NBLOCK ); 179 mem.aPool[x].u.list.prev = i; 180 } 181 mem.aiFreelist[iLogsize] = i; 182 } 183 184 /* 185 ** Enter the mutex mem.mutex. Allocate it if it is not already allocated. 186 ** 187 ** Also: Initialize the memory allocation subsystem the first time 188 ** this routine is called. 189 */ 190 static void memsys5Enter(void){ 191 if( mem.mutex==0 ){ 192 int i; 193 assert( sizeof(Mem5Block)==POW2_MIN ); 194 assert( (SQLITE_POW2_MEMORY_SIZE % POW2_MAX)==0 ); 195 assert( SQLITE_POW2_MEMORY_SIZE>=POW2_MAX ); 196 mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); 197 sqlite3_mutex_enter(mem.mutex); 198 for(i=0; i<NSIZE; i++) mem.aiFreelist[i] = -1; 199 for(i=0; i<=NBLOCK-SZ_MAX; i += SZ_MAX){ 200 mem.aCtrl[i] = (NSIZE-1) | CTRL_FREE; 201 memsys5Link(i, NSIZE-1); 202 } 203 }else{ 204 sqlite3_mutex_enter(mem.mutex); 205 } 206 } 207 208 /* 209 ** Return the amount of memory currently checked out. 210 */ 211 sqlite3_int64 sqlite3_memory_used(void){ 212 return mem.currentOut; 213 } 214 215 /* 216 ** Return the maximum amount of memory that has ever been 217 ** checked out since either the beginning of this process 218 ** or since the most recent reset. 219 */ 220 sqlite3_int64 sqlite3_memory_highwater(int resetFlag){ 221 sqlite3_int64 n; 222 memsys5Enter(); 223 n = mem.maxOut; 224 if( resetFlag ){ 225 mem.maxOut = mem.currentOut; 226 } 227 sqlite3_mutex_leave(mem.mutex); 228 return n; 229 } 230 231 232 /* 233 ** Trigger the alarm 234 */ 235 static void memsys5Alarm(int nByte){ 236 void (*xCallback)(void*,sqlite3_int64,int); 237 sqlite3_int64 nowUsed; 238 void *pArg; 239 if( mem.alarmCallback==0 || mem.alarmBusy ) return; 240 mem.alarmBusy = 1; 241 xCallback = mem.alarmCallback; 242 nowUsed = mem.currentOut; 243 pArg = mem.alarmArg; 244 sqlite3_mutex_leave(mem.mutex); 245 xCallback(pArg, nowUsed, nByte); 246 sqlite3_mutex_enter(mem.mutex); 247 mem.alarmBusy = 0; 248 } 249 250 /* 251 ** Change the alarm callback. 252 ** 253 ** This is a no-op for the static memory allocator. The purpose 254 ** of the memory alarm is to support sqlite3_soft_heap_limit(). 255 ** But with this memory allocator, the soft_heap_limit is really 256 ** a hard limit that is fixed at SQLITE_POW2_MEMORY_SIZE. 257 */ 258 int sqlite3_memory_alarm( 259 void(*xCallback)(void *pArg, sqlite3_int64 used,int N), 260 void *pArg, 261 sqlite3_int64 iThreshold 262 ){ 263 memsys5Enter(); 264 mem.alarmCallback = xCallback; 265 mem.alarmArg = pArg; 266 mem.alarmThreshold = iThreshold; 267 sqlite3_mutex_leave(mem.mutex); 268 return SQLITE_OK; 269 } 270 271 /* 272 ** Return the size of an outstanding allocation, in bytes. The 273 ** size returned omits the 8-byte header overhead. This only 274 ** works for chunks that are currently checked out. 275 */ 276 int sqlite3MallocSize(void *p){ 277 int iSize = 0; 278 if( p ){ 279 int i = ((Mem5Block*)p) - mem.aPool; 280 assert( i>=0 && i<NBLOCK ); 281 iSize = 1 << ((mem.aCtrl[i]&CTRL_LOGSIZE) + SQLITE_POW2_LOGMIN); 282 } 283 return iSize; 284 } 285 286 /* 287 ** Find the first entry on the freelist iLogsize. Unlink that 288 ** entry and return its index. 289 */ 290 static int memsys5UnlinkFirst(int iLogsize){ 291 int i; 292 int iFirst; 293 294 assert( iLogsize>=0 && iLogsize<NSIZE ); 295 i = iFirst = mem.aiFreelist[iLogsize]; 296 assert( iFirst>=0 ); 297 while( i>0 ){ 298 if( i<iFirst ) iFirst = i; 299 i = mem.aPool[i].u.list.next; 300 } 301 memsys5Unlink(iFirst, iLogsize); 302 return iFirst; 303 } 304 305 /* 306 ** Return a block of memory of at least nBytes in size. 307 ** Return NULL if unable. 308 */ 309 static void *memsys5Malloc(int nByte){ 310 int i; /* Index of a mem.aPool[] slot */ 311 int iBin; /* Index into mem.aiFreelist[] */ 312 int iFullSz; /* Size of allocation rounded up to power of 2 */ 313 int iLogsize; /* Log2 of iFullSz/POW2_MIN */ 314 315 assert( sqlite3_mutex_held(mem.mutex) ); 316 317 /* Keep track of the maximum allocation request. Even unfulfilled 318 ** requests are counted */ 319 if( nByte>mem.maxRequest ){ 320 mem.maxRequest = nByte; 321 } 322 323 /* Simulate a memory allocation fault */ 324 if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ) return 0; 325 326 /* Round nByte up to the next valid power of two */ 327 if( nByte>POW2_MAX ) return 0; 328 for(iFullSz=POW2_MIN, iLogsize=0; iFullSz<nByte; iFullSz *= 2, iLogsize++){} 329 330 /* If we will be over the memory alarm threshold after this allocation, 331 ** then trigger the memory overflow alarm */ 332 if( mem.alarmCallback!=0 && mem.currentOut+iFullSz>=mem.alarmThreshold ){ 333 memsys5Alarm(iFullSz); 334 } 335 336 /* Make sure mem.aiFreelist[iLogsize] contains at least one free 337 ** block. If not, then split a block of the next larger power of 338 ** two in order to create a new free block of size iLogsize. 339 */ 340 for(iBin=iLogsize; mem.aiFreelist[iBin]<0 && iBin<NSIZE; iBin++){} 341 if( iBin>=NSIZE ) return 0; 342 i = memsys5UnlinkFirst(iBin); 343 while( iBin>iLogsize ){ 344 int newSize; 345 346 iBin--; 347 newSize = 1 << iBin; 348 mem.aCtrl[i+newSize] = CTRL_FREE | iBin; 349 memsys5Link(i+newSize, iBin); 350 } 351 mem.aCtrl[i] = iLogsize; 352 353 /* Update allocator performance statistics. */ 354 mem.nAlloc++; 355 mem.totalAlloc += iFullSz; 356 mem.totalExcess += iFullSz - nByte; 357 mem.currentCount++; 358 mem.currentOut += iFullSz; 359 if( mem.maxCount<mem.currentCount ) mem.maxCount = mem.currentCount; 360 if( mem.maxOut<mem.currentOut ) mem.maxOut = mem.currentOut; 361 362 /* Return a pointer to the allocated memory. */ 363 return (void*)&mem.aPool[i]; 364 } 365 366 /* 367 ** Free an outstanding memory allocation. 368 */ 369 void memsys5Free(void *pOld){ 370 u32 size, iLogsize; 371 int i; 372 373 i = ((Mem5Block*)pOld) - mem.aPool; 374 assert( sqlite3_mutex_held(mem.mutex) ); 375 assert( i>=0 && i<NBLOCK ); 376 assert( (mem.aCtrl[i] & CTRL_FREE)==0 ); 377 iLogsize = mem.aCtrl[i] & CTRL_LOGSIZE; 378 size = 1<<iLogsize; 379 assert( i+size-1<NBLOCK ); 380 mem.aCtrl[i] |= CTRL_FREE; 381 mem.aCtrl[i+size-1] |= CTRL_FREE; 382 assert( mem.currentCount>0 ); 383 assert( mem.currentOut>=0 ); 384 mem.currentCount--; 385 mem.currentOut -= size*POW2_MIN; 386 assert( mem.currentOut>0 || mem.currentCount==0 ); 387 assert( mem.currentCount>0 || mem.currentOut==0 ); 388 389 mem.aCtrl[i] = CTRL_FREE | iLogsize; 390 while( iLogsize<NSIZE-1 ){ 391 int iBuddy; 392 393 if( (i>>iLogsize) & 1 ){ 394 iBuddy = i - size; 395 }else{ 396 iBuddy = i + size; 397 } 398 assert( iBuddy>=0 && iBuddy<NBLOCK ); 399 if( mem.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break; 400 memsys5Unlink(iBuddy, iLogsize); 401 iLogsize++; 402 if( iBuddy<i ){ 403 mem.aCtrl[iBuddy] = CTRL_FREE | iLogsize; 404 mem.aCtrl[i] = 0; 405 i = iBuddy; 406 }else{ 407 mem.aCtrl[i] = CTRL_FREE | iLogsize; 408 mem.aCtrl[iBuddy] = 0; 409 } 410 size *= 2; 411 } 412 memsys5Link(i, iLogsize); 413 } 414 415 /* 416 ** Allocate nBytes of memory 417 */ 418 void *sqlite3_malloc(int nBytes){ 419 sqlite3_int64 *p = 0; 420 if( nBytes>0 ){ 421 memsys5Enter(); 422 p = memsys5Malloc(nBytes); 423 sqlite3_mutex_leave(mem.mutex); 424 } 425 return (void*)p; 426 } 427 428 /* 429 ** Free memory. 430 */ 431 void sqlite3_free(void *pPrior){ 432 if( pPrior==0 ){ 433 return; 434 } 435 assert( mem.mutex!=0 ); 436 sqlite3_mutex_enter(mem.mutex); 437 memsys5Free(pPrior); 438 sqlite3_mutex_leave(mem.mutex); 439 } 440 441 /* 442 ** Change the size of an existing memory allocation 443 */ 444 void *sqlite3_realloc(void *pPrior, int nBytes){ 445 int nOld; 446 void *p; 447 if( pPrior==0 ){ 448 return sqlite3_malloc(nBytes); 449 } 450 if( nBytes<=0 ){ 451 sqlite3_free(pPrior); 452 return 0; 453 } 454 assert( mem.mutex!=0 ); 455 nOld = sqlite3MallocSize(pPrior); 456 if( nBytes<=nOld ){ 457 return pPrior; 458 } 459 sqlite3_mutex_enter(mem.mutex); 460 p = memsys5Malloc(nBytes); 461 if( p ){ 462 memcpy(p, pPrior, nOld); 463 memsys5Free(pPrior); 464 } 465 sqlite3_mutex_leave(mem.mutex); 466 return p; 467 } 468 469 /* 470 ** Open the file indicated and write a log of all unfreed memory 471 ** allocations into that log. 472 */ 473 void sqlite3MemdebugDump(const char *zFilename){ 474 #ifdef SQLITE_DEBUG 475 FILE *out; 476 int i, j, n; 477 478 if( zFilename==0 || zFilename[0]==0 ){ 479 out = stdout; 480 }else{ 481 out = fopen(zFilename, "w"); 482 if( out==0 ){ 483 fprintf(stderr, "** Unable to output memory debug output log: %s **\n", 484 zFilename); 485 return; 486 } 487 } 488 memsys5Enter(); 489 for(i=0; i<NSIZE; i++){ 490 for(n=0, j=mem.aiFreelist[i]; j>=0; j = mem.aPool[j].u.list.next, n++){} 491 fprintf(out, "freelist items of size %d: %d\n", POW2_MIN << i, n); 492 } 493 fprintf(out, "mem.nAlloc = %llu\n", mem.nAlloc); 494 fprintf(out, "mem.totalAlloc = %llu\n", mem.totalAlloc); 495 fprintf(out, "mem.totalExcess = %llu\n", mem.totalExcess); 496 fprintf(out, "mem.currentOut = %u\n", mem.currentOut); 497 fprintf(out, "mem.currentCount = %u\n", mem.currentCount); 498 fprintf(out, "mem.maxOut = %u\n", mem.maxOut); 499 fprintf(out, "mem.maxCount = %u\n", mem.maxCount); 500 fprintf(out, "mem.maxRequest = %u\n", mem.maxRequest); 501 sqlite3_mutex_leave(mem.mutex); 502 if( out==stdout ){ 503 fflush(stdout); 504 }else{ 505 fclose(out); 506 } 507 #endif 508 } 509 510 511 #endif /* !SQLITE_POW2_MEMORY_SIZE */ 512