xref: /sqlite-3.40.0/src/mem5.c (revision 8a29dfde)
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