Annotation of embedaddon/sqlite3/src/mem1.c, revision 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>