aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/sqlite/win32/mem1.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/sqlite/win32/mem1.c')
-rwxr-xr-xlibraries/sqlite/win32/mem1.c229
1 files changed, 229 insertions, 0 deletions
diff --git a/libraries/sqlite/win32/mem1.c b/libraries/sqlite/win32/mem1.c
new file mode 100755
index 0000000..1e9fcfa
--- /dev/null
+++ b/libraries/sqlite/win32/mem1.c
@@ -0,0 +1,229 @@
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.10 2007/09/02 17:50:35 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_OMIT_MEMORY_ALLOCATION)
24
25/*
26** We will eventually construct multiple memory allocation subsystems
27** suitable for use in various contexts:
28**
29** * Normal multi-threaded builds
30** * Normal single-threaded builds
31** * Debugging builds
32**
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.
37*/
38#include "sqliteInt.h"
39
40/*
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.
45*/
46static struct {
47 /*
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
52 ** callbacks.
53 */
54 sqlite3_int64 alarmThreshold;
55 void (*alarmCallback)(void*, sqlite3_int64,int);
56 void *alarmArg;
57 int alarmBusy;
58
59 /*
60 ** Mutex to control access to the memory allocation subsystem.
61 */
62 sqlite3_mutex *mutex;
63
64 /*
65 ** Current allocation and high-water mark.
66 */
67 sqlite3_int64 nowUsed;
68 sqlite3_int64 mxUsed;
69
70
71} mem;
72
73/*
74** Enter the mutex mem.mutex. Allocate it if it is not already allocated.
75*/
76static void enterMem(void){
77 if( mem.mutex==0 ){
78 mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
79 }
80 sqlite3_mutex_enter(mem.mutex);
81}
82
83/*
84** Return the amount of memory currently checked out.
85*/
86sqlite3_int64 sqlite3_memory_used(void){
87 sqlite3_int64 n;
88 enterMem();
89 n = mem.nowUsed;
90 sqlite3_mutex_leave(mem.mutex);
91 return n;
92}
93
94/*
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.
98*/
99sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
100 sqlite3_int64 n;
101 enterMem();
102 n = mem.mxUsed;
103 if( resetFlag ){
104 mem.mxUsed = mem.nowUsed;
105 }
106 sqlite3_mutex_leave(mem.mutex);
107 return n;
108}
109
110/*
111** Change the alarm callback
112*/
113int sqlite3_memory_alarm(
114 void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
115 void *pArg,
116 sqlite3_int64 iThreshold
117){
118 enterMem();
119 mem.alarmCallback = xCallback;
120 mem.alarmArg = pArg;
121 mem.alarmThreshold = iThreshold;
122 sqlite3_mutex_leave(mem.mutex);
123 return SQLITE_OK;
124}
125
126/*
127** Trigger the alarm
128*/
129static void sqlite3MemsysAlarm(int nByte){
130 void (*xCallback)(void*,sqlite3_int64,int);
131 sqlite3_int64 nowUsed;
132 void *pArg;
133 if( mem.alarmCallback==0 || mem.alarmBusy ) return;
134 mem.alarmBusy = 1;
135 xCallback = mem.alarmCallback;
136 nowUsed = mem.nowUsed;
137 pArg = mem.alarmArg;
138 sqlite3_mutex_leave(mem.mutex);
139 xCallback(pArg, nowUsed, nByte);
140 sqlite3_mutex_enter(mem.mutex);
141 mem.alarmBusy = 0;
142}
143
144/*
145** Allocate nBytes of memory
146*/
147void *sqlite3_malloc(int nBytes){
148 sqlite3_int64 *p = 0;
149 if( nBytes>0 ){
150 enterMem();
151 if( mem.alarmCallback!=0 && mem.nowUsed+nBytes>=mem.alarmThreshold ){
152 sqlite3MemsysAlarm(nBytes);
153 }
154 p = malloc(nBytes+8);
155 if( p==0 ){
156 sqlite3MemsysAlarm(nBytes);
157 p = malloc(nBytes+8);
158 }
159 if( p ){
160 p[0] = nBytes;
161 p++;
162 mem.nowUsed += nBytes;
163 if( mem.nowUsed>mem.mxUsed ){
164 mem.mxUsed = mem.nowUsed;
165 }
166 }
167 sqlite3_mutex_leave(mem.mutex);
168 }
169 return (void*)p;
170}
171
172/*
173** Free memory.
174*/
175void sqlite3_free(void *pPrior){
176 sqlite3_int64 *p;
177 int nByte;
178 if( pPrior==0 ){
179 return;
180 }
181 assert( mem.mutex!=0 );
182 p = pPrior;
183 p--;
184 nByte = (int)*p;
185 sqlite3_mutex_enter(mem.mutex);
186 mem.nowUsed -= nByte;
187 free(p);
188 sqlite3_mutex_leave(mem.mutex);
189}
190
191/*
192** Change the size of an existing memory allocation
193*/
194void *sqlite3_realloc(void *pPrior, int nBytes){
195 int nOld;
196 sqlite3_int64 *p;
197 if( pPrior==0 ){
198 return sqlite3_malloc(nBytes);
199 }
200 if( nBytes<=0 ){
201 sqlite3_free(pPrior);
202 return 0;
203 }
204 p = pPrior;
205 p--;
206 nOld = (int)p[0];
207 assert( mem.mutex!=0 );
208 sqlite3_mutex_enter(mem.mutex);
209 if( mem.nowUsed+nBytes-nOld>=mem.alarmThreshold ){
210 sqlite3MemsysAlarm(nBytes-nOld);
211 }
212 p = realloc(p, nBytes+8);
213 if( p==0 ){
214 sqlite3MemsysAlarm(nBytes);
215 p = realloc(p, nBytes+8);
216 }
217 if( p ){
218 p[0] = nBytes;
219 p++;
220 mem.nowUsed += nBytes-nOld;
221 if( mem.nowUsed>mem.mxUsed ){
222 mem.mxUsed = mem.nowUsed;
223 }
224 }
225 sqlite3_mutex_leave(mem.mutex);
226 return (void*)p;
227}
228
229#endif /* !SQLITE_MEMDEBUG && !SQLITE_OMIT_MEMORY_ALLOCATION */