Annotation of embedaddon/sqlite3/src/mem1.c, revision 1.1.1.1
1.1 misho 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: **
13: ** This file contains low-level memory allocation drivers for when
14: ** SQLite will use the standard C-library malloc/realloc/free interface
15: ** to obtain the memory it needs.
16: **
17: ** This file contains implementations of the low-level memory allocation
18: ** routines specified in the sqlite3_mem_methods object.
19: */
20: #include "sqliteInt.h"
21:
22: /*
23: ** This version of the memory allocator is the default. It is
24: ** used when no other memory allocator is specified using compile-time
25: ** macros.
26: */
27: #ifdef SQLITE_SYSTEM_MALLOC
28:
29: /*
30: ** Windows systems have malloc_usable_size() but it is called _msize()
31: */
32: #if !defined(HAVE_MALLOC_USABLE_SIZE) && SQLITE_OS_WIN
33: # define HAVE_MALLOC_USABLE_SIZE 1
34: # define malloc_usable_size _msize
35: #endif
36:
37: #if defined(__APPLE__)
38:
39: /*
40: ** Use the zone allocator available on apple products
41: */
42: #include <sys/sysctl.h>
43: #include <malloc/malloc.h>
44: #include <libkern/OSAtomic.h>
45: static malloc_zone_t* _sqliteZone_;
46: #define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))
47: #define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));
48: #define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y))
49: #define SQLITE_MALLOCSIZE(x) \
50: (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x))
51:
52: #else /* if not __APPLE__ */
53:
54: /*
55: ** Use standard C library malloc and free on non-Apple systems.
56: */
57: #define SQLITE_MALLOC(x) malloc(x)
58: #define SQLITE_FREE(x) free(x)
59: #define SQLITE_REALLOC(x,y) realloc((x),(y))
60:
61: #ifdef HAVE_MALLOC_USABLE_SIZE
62: #include <malloc.h>
63: #define SQLITE_MALLOCSIZE(x) malloc_usable_size(x)
64: #else
65: #undef SQLITE_MALLOCSIZE
66: #endif
67:
68: #endif /* __APPLE__ or not __APPLE__ */
69:
70: /*
71: ** Like malloc(), but remember the size of the allocation
72: ** so that we can find it later using sqlite3MemSize().
73: **
74: ** For this low-level routine, we are guaranteed that nByte>0 because
75: ** cases of nByte<=0 will be intercepted and dealt with by higher level
76: ** routines.
77: */
78: static void *sqlite3MemMalloc(int nByte){
79: #ifdef SQLITE_MALLOCSIZE
80: void *p = SQLITE_MALLOC( nByte );
81: if( p==0 ){
82: testcase( sqlite3GlobalConfig.xLog!=0 );
83: sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
84: }
85: return p;
86: #else
87: sqlite3_int64 *p;
88: assert( nByte>0 );
89: nByte = ROUND8(nByte);
90: p = SQLITE_MALLOC( nByte+8 );
91: if( p ){
92: p[0] = nByte;
93: p++;
94: }else{
95: testcase( sqlite3GlobalConfig.xLog!=0 );
96: sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
97: }
98: return (void *)p;
99: #endif
100: }
101:
102: /*
103: ** Like free() but works for allocations obtained from sqlite3MemMalloc()
104: ** or sqlite3MemRealloc().
105: **
106: ** For this low-level routine, we already know that pPrior!=0 since
107: ** cases where pPrior==0 will have been intecepted and dealt with
108: ** by higher-level routines.
109: */
110: static void sqlite3MemFree(void *pPrior){
111: #ifdef SQLITE_MALLOCSIZE
112: SQLITE_FREE(pPrior);
113: #else
114: sqlite3_int64 *p = (sqlite3_int64*)pPrior;
115: assert( pPrior!=0 );
116: p--;
117: SQLITE_FREE(p);
118: #endif
119: }
120:
121: /*
122: ** Report the allocated size of a prior return from xMalloc()
123: ** or xRealloc().
124: */
125: static int sqlite3MemSize(void *pPrior){
126: #ifdef SQLITE_MALLOCSIZE
127: return pPrior ? (int)SQLITE_MALLOCSIZE(pPrior) : 0;
128: #else
129: sqlite3_int64 *p;
130: if( pPrior==0 ) return 0;
131: p = (sqlite3_int64*)pPrior;
132: p--;
133: return (int)p[0];
134: #endif
135: }
136:
137: /*
138: ** Like realloc(). Resize an allocation previously obtained from
139: ** sqlite3MemMalloc().
140: **
141: ** For this low-level interface, we know that pPrior!=0. Cases where
142: ** pPrior==0 while have been intercepted by higher-level routine and
143: ** redirected to xMalloc. Similarly, we know that nByte>0 becauses
144: ** cases where nByte<=0 will have been intercepted by higher-level
145: ** routines and redirected to xFree.
146: */
147: static void *sqlite3MemRealloc(void *pPrior, int nByte){
148: #ifdef SQLITE_MALLOCSIZE
149: void *p = SQLITE_REALLOC(pPrior, nByte);
150: if( p==0 ){
151: testcase( sqlite3GlobalConfig.xLog!=0 );
152: sqlite3_log(SQLITE_NOMEM,
153: "failed memory resize %u to %u bytes",
154: SQLITE_MALLOCSIZE(pPrior), nByte);
155: }
156: return p;
157: #else
158: sqlite3_int64 *p = (sqlite3_int64*)pPrior;
159: assert( pPrior!=0 && nByte>0 );
160: assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */
161: p--;
162: p = SQLITE_REALLOC(p, nByte+8 );
163: if( p ){
164: p[0] = nByte;
165: p++;
166: }else{
167: testcase( sqlite3GlobalConfig.xLog!=0 );
168: sqlite3_log(SQLITE_NOMEM,
169: "failed memory resize %u to %u bytes",
170: sqlite3MemSize(pPrior), nByte);
171: }
172: return (void*)p;
173: #endif
174: }
175:
176: /*
177: ** Round up a request size to the next valid allocation size.
178: */
179: static int sqlite3MemRoundup(int n){
180: return ROUND8(n);
181: }
182:
183: /*
184: ** Initialize this module.
185: */
186: static int sqlite3MemInit(void *NotUsed){
187: #if defined(__APPLE__)
188: int cpuCount;
189: size_t len;
190: if( _sqliteZone_ ){
191: return SQLITE_OK;
192: }
193: len = sizeof(cpuCount);
194: /* One usually wants to use hw.acctivecpu for MT decisions, but not here */
195: sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0);
196: if( cpuCount>1 ){
197: /* defer MT decisions to system malloc */
198: _sqliteZone_ = malloc_default_zone();
199: }else{
200: /* only 1 core, use our own zone to contention over global locks,
201: ** e.g. we have our own dedicated locks */
202: bool success;
203: malloc_zone_t* newzone = malloc_create_zone(4096, 0);
204: malloc_set_zone_name(newzone, "Sqlite_Heap");
205: do{
206: success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone,
207: (void * volatile *)&_sqliteZone_);
208: }while(!_sqliteZone_);
209: if( !success ){
210: /* somebody registered a zone first */
211: malloc_destroy_zone(newzone);
212: }
213: }
214: #endif
215: UNUSED_PARAMETER(NotUsed);
216: return SQLITE_OK;
217: }
218:
219: /*
220: ** Deinitialize this module.
221: */
222: static void sqlite3MemShutdown(void *NotUsed){
223: UNUSED_PARAMETER(NotUsed);
224: return;
225: }
226:
227: /*
228: ** This routine is the only routine in this file with external linkage.
229: **
230: ** Populate the low-level memory allocation function pointers in
231: ** sqlite3GlobalConfig.m with pointers to the routines in this file.
232: */
233: void sqlite3MemSetDefault(void){
234: static const sqlite3_mem_methods defaultMethods = {
235: sqlite3MemMalloc,
236: sqlite3MemFree,
237: sqlite3MemRealloc,
238: sqlite3MemSize,
239: sqlite3MemRoundup,
240: sqlite3MemInit,
241: sqlite3MemShutdown,
242: 0
243: };
244: sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
245: }
246:
247: #endif /* SQLITE_SYSTEM_MALLOC */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>