Merge from 1.2 branch.
4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
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.
11 *************************************************************************
12 ** This file contains the C functions that implement a memory
13 ** allocation subsystem for use by SQLite.
19 ** This version of the memory allocator is the default. It is
20 ** used when no other memory allocator is specified using compile-time
23 #if !defined(SQLITE_MEMDEBUG) && !defined(SQLITE_OMIT_MEMORY_ALLOCATION)
26 ** We will eventually construct multiple memory allocation subsystems
27 ** suitable for use in various contexts:
29 ** * Normal multi-threaded builds
30 ** * Normal single-threaded builds
33 ** This initial version is suitable for use in normal multi-threaded
34 ** builds. We envision that alternative versions will be stored in
35 ** separate source files. #ifdefs will be used to select the code from
36 ** one of the various memN.c source files for use in any given build.
38 #include "sqliteInt.h"
41 ** All of the static variables used by this module are collected
42 ** into a single structure named "mem". This is to keep the
43 ** static variables organized and to reduce namespace pollution
44 ** when this module is combined with other in the amalgamation.
48 ** The alarm callback and its arguments. The mem.mutex lock will
49 ** be held while the callback is running. Recursive calls into
50 ** the memory subsystem are allowed, but no new callbacks will be
51 ** issued. The alarmBusy variable is set to prevent recursive
54 sqlite3_int64 alarmThreshold;
55 void (*alarmCallback)(void*, sqlite3_int64,int);
60 ** Mutex to control access to the memory allocation subsystem.
65 ** Current allocation and high-water mark.
67 sqlite3_int64 nowUsed;
74 ** Enter the mutex mem.mutex. Allocate it if it is not already allocated.
76 static void enterMem(void){
78 mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
80 sqlite3_mutex_enter(mem.mutex);
84 ** Return the amount of memory currently checked out.
86 sqlite3_int64 sqlite3_memory_used(void){
90 sqlite3_mutex_leave(mem.mutex);
95 ** Return the maximum amount of memory that has ever been
96 ** checked out since either the beginning of this process
97 ** or since the most recent reset.
99 sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
104 mem.mxUsed = mem.nowUsed;
106 sqlite3_mutex_leave(mem.mutex);
111 ** Change the alarm callback
113 int sqlite3_memory_alarm(
114 void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
116 sqlite3_int64 iThreshold
119 mem.alarmCallback = xCallback;
121 mem.alarmThreshold = iThreshold;
122 sqlite3_mutex_leave(mem.mutex);
129 static void sqlite3MemsysAlarm(int nByte){
130 void (*xCallback)(void*,sqlite3_int64,int);
131 sqlite3_int64 nowUsed;
133 if( mem.alarmCallback==0 || mem.alarmBusy ) return;
135 xCallback = mem.alarmCallback;
136 nowUsed = mem.nowUsed;
138 sqlite3_mutex_leave(mem.mutex);
139 xCallback(pArg, nowUsed, nByte);
140 sqlite3_mutex_enter(mem.mutex);
145 ** Allocate nBytes of memory
147 void *sqlite3_malloc(int nBytes){
148 sqlite3_int64 *p = 0;
151 if( mem.alarmCallback!=0 && mem.nowUsed+nBytes>=mem.alarmThreshold ){
152 sqlite3MemsysAlarm(nBytes);
154 p = malloc(nBytes+8);
156 sqlite3MemsysAlarm(nBytes);
157 p = malloc(nBytes+8);
162 mem.nowUsed += nBytes;
163 if( mem.nowUsed>mem.mxUsed ){
164 mem.mxUsed = mem.nowUsed;
167 sqlite3_mutex_leave(mem.mutex);
175 void sqlite3_free(void *pPrior){
181 assert( mem.mutex!=0 );
185 sqlite3_mutex_enter(mem.mutex);
186 mem.nowUsed -= nByte;
188 sqlite3_mutex_leave(mem.mutex);
192 ** Change the size of an existing memory allocation
194 void *sqlite3_realloc(void *pPrior, int nBytes){
198 return sqlite3_malloc(nBytes);
201 sqlite3_free(pPrior);
207 assert( mem.mutex!=0 );
208 sqlite3_mutex_enter(mem.mutex);
209 if( mem.nowUsed+nBytes-nOld>=mem.alarmThreshold ){
210 sqlite3MemsysAlarm(nBytes-nOld);
212 p = realloc(p, nBytes+8);
214 sqlite3MemsysAlarm(nBytes);
215 p = realloc(p, nBytes+8);
220 mem.nowUsed += nBytes-nOld;
221 if( mem.nowUsed>mem.mxUsed ){
222 mem.mxUsed = mem.nowUsed;
225 sqlite3_mutex_leave(mem.mutex);
229 #endif /* !SQLITE_MEMDEBUG && !SQLITE_OMIT_MEMORY_ALLOCATION */