1 /* 2 ** 2007 August 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 ** $Id: mem1.c,v 1.14 2007/11/29 18:36:49 drh Exp $ 16 */ 17 18 /* 19 ** This version of the memory allocator is the default. It is 20 ** used when no other memory allocator is specified using compile-time 21 ** macros. 22 */ 23 #if !defined(SQLITE_MEMDEBUG) && !defined(SQLITE_MEMORY_SIZE) \ 24 && !defined(SQLITE_MMAP_HEAP_SIZE) 25 26 /* 27 ** We will eventually construct multiple memory allocation subsystems 28 ** suitable for use in various contexts: 29 ** 30 ** * Normal multi-threaded builds 31 ** * Normal single-threaded builds 32 ** * Debugging builds 33 ** 34 ** This initial version is suitable for use in normal multi-threaded 35 ** builds. We envision that alternative versions will be stored in 36 ** separate source files. #ifdefs will be used to select the code from 37 ** one of the various memN.c source files for use in any given build. 38 */ 39 #include "sqliteInt.h" 40 41 /* 42 ** All of the static variables used by this module are collected 43 ** into a single structure named "mem". This is to keep the 44 ** static variables organized and to reduce namespace pollution 45 ** when this module is combined with other in the amalgamation. 46 */ 47 static struct { 48 /* 49 ** The alarm callback and its arguments. The mem.mutex lock will 50 ** be held while the callback is running. Recursive calls into 51 ** the memory subsystem are allowed, but no new callbacks will be 52 ** issued. The alarmBusy variable is set to prevent recursive 53 ** callbacks. 54 */ 55 sqlite3_int64 alarmThreshold; 56 void (*alarmCallback)(void*, sqlite3_int64,int); 57 void *alarmArg; 58 int alarmBusy; 59 60 /* 61 ** Mutex to control access to the memory allocation subsystem. 62 */ 63 sqlite3_mutex *mutex; 64 65 /* 66 ** Current allocation and high-water mark. 67 */ 68 sqlite3_int64 nowUsed; 69 sqlite3_int64 mxUsed; 70 71 72 } mem; 73 74 /* 75 ** Enter the mutex mem.mutex. Allocate it if it is not already allocated. 76 */ 77 static void enterMem(void){ 78 if( mem.mutex==0 ){ 79 mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); 80 } 81 sqlite3_mutex_enter(mem.mutex); 82 } 83 84 /* 85 ** Return the amount of memory currently checked out. 86 */ 87 sqlite3_int64 sqlite3_memory_used(void){ 88 sqlite3_int64 n; 89 enterMem(); 90 n = mem.nowUsed; 91 sqlite3_mutex_leave(mem.mutex); 92 return n; 93 } 94 95 /* 96 ** Return the maximum amount of memory that has ever been 97 ** checked out since either the beginning of this process 98 ** or since the most recent reset. 99 */ 100 sqlite3_int64 sqlite3_memory_highwater(int resetFlag){ 101 sqlite3_int64 n; 102 enterMem(); 103 n = mem.mxUsed; 104 if( resetFlag ){ 105 mem.mxUsed = mem.nowUsed; 106 } 107 sqlite3_mutex_leave(mem.mutex); 108 return n; 109 } 110 111 /* 112 ** Change the alarm callback 113 */ 114 int sqlite3_memory_alarm( 115 void(*xCallback)(void *pArg, sqlite3_int64 used,int N), 116 void *pArg, 117 sqlite3_int64 iThreshold 118 ){ 119 enterMem(); 120 mem.alarmCallback = xCallback; 121 mem.alarmArg = pArg; 122 mem.alarmThreshold = iThreshold; 123 sqlite3_mutex_leave(mem.mutex); 124 return SQLITE_OK; 125 } 126 127 /* 128 ** Trigger the alarm 129 */ 130 static void sqlite3MemsysAlarm(int nByte){ 131 void (*xCallback)(void*,sqlite3_int64,int); 132 sqlite3_int64 nowUsed; 133 void *pArg; 134 if( mem.alarmCallback==0 || mem.alarmBusy ) return; 135 mem.alarmBusy = 1; 136 xCallback = mem.alarmCallback; 137 nowUsed = mem.nowUsed; 138 pArg = mem.alarmArg; 139 sqlite3_mutex_leave(mem.mutex); 140 xCallback(pArg, nowUsed, nByte); 141 sqlite3_mutex_enter(mem.mutex); 142 mem.alarmBusy = 0; 143 } 144 145 /* 146 ** Allocate nBytes of memory 147 */ 148 void *sqlite3_malloc(int nBytes){ 149 sqlite3_int64 *p = 0; 150 if( nBytes>0 ){ 151 enterMem(); 152 if( mem.alarmCallback!=0 && mem.nowUsed+nBytes>=mem.alarmThreshold ){ 153 sqlite3MemsysAlarm(nBytes); 154 } 155 p = malloc(nBytes+8); 156 if( p==0 ){ 157 sqlite3MemsysAlarm(nBytes); 158 p = malloc(nBytes+8); 159 } 160 if( p ){ 161 p[0] = nBytes; 162 p++; 163 mem.nowUsed += nBytes; 164 if( mem.nowUsed>mem.mxUsed ){ 165 mem.mxUsed = mem.nowUsed; 166 } 167 } 168 sqlite3_mutex_leave(mem.mutex); 169 } 170 return (void*)p; 171 } 172 173 /* 174 ** Free memory. 175 */ 176 void sqlite3_free(void *pPrior){ 177 sqlite3_int64 *p; 178 int nByte; 179 if( pPrior==0 ){ 180 return; 181 } 182 assert( mem.mutex!=0 ); 183 p = pPrior; 184 p--; 185 nByte = (int)*p; 186 sqlite3_mutex_enter(mem.mutex); 187 mem.nowUsed -= nByte; 188 free(p); 189 sqlite3_mutex_leave(mem.mutex); 190 } 191 192 /* 193 ** Change the size of an existing memory allocation 194 */ 195 void *sqlite3_realloc(void *pPrior, int nBytes){ 196 int nOld; 197 sqlite3_int64 *p; 198 if( pPrior==0 ){ 199 return sqlite3_malloc(nBytes); 200 } 201 if( nBytes<=0 ){ 202 sqlite3_free(pPrior); 203 return 0; 204 } 205 p = pPrior; 206 p--; 207 nOld = (int)p[0]; 208 assert( mem.mutex!=0 ); 209 sqlite3_mutex_enter(mem.mutex); 210 if( mem.nowUsed+nBytes-nOld>=mem.alarmThreshold ){ 211 sqlite3MemsysAlarm(nBytes-nOld); 212 } 213 p = realloc(p, nBytes+8); 214 if( p==0 ){ 215 sqlite3MemsysAlarm(nBytes); 216 p = pPrior; 217 p--; 218 p = realloc(p, nBytes+8); 219 } 220 if( p ){ 221 p[0] = nBytes; 222 p++; 223 mem.nowUsed += nBytes-nOld; 224 if( mem.nowUsed>mem.mxUsed ){ 225 mem.mxUsed = mem.nowUsed; 226 } 227 } 228 sqlite3_mutex_leave(mem.mutex); 229 return (void*)p; 230 } 231 232 #endif /* !SQLITE_MEMDEBUG && !SQLITE_OMIT_MEMORY_ALLOCATION */ 233