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>