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>