Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
mem1.c292 linesDownload Raw Back to src
1/*2** 2007 August 143**4** The author disclaims copyright to this source code.  In place of5** 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 when14** SQLite will use the standard C-library malloc/realloc/free interface15** to obtain the memory it needs.16**17** This file contains implementations of the low-level memory allocation18** routines specified in the sqlite3_mem_methods object.  The content of19** this file is only used if SQLITE_SYSTEM_MALLOC is defined.  The20** SQLITE_SYSTEM_MALLOC macro is defined automatically if neither the21** SQLITE_MEMDEBUG nor the SQLITE_WIN32_MALLOC macros are defined.  The22** default configuration is to use memory allocation routines in this23** file.24**25** C-preprocessor macro summary:26**27**    HAVE_MALLOC_USABLE_SIZE     The configure script sets this symbol if28**                                the malloc_usable_size() interface exists29**                                on the target platform.  Or, this symbol30**                                can be set manually, if desired.31**                                If an equivalent interface exists by32**                                a different name, using a separate -D33**                                option to rename it.34**35**    SQLITE_WITHOUT_ZONEMALLOC   Some older macs lack support for the zone36**                                memory allocator.  Set this symbol to enable37**                                building on older macs.38**39**    SQLITE_WITHOUT_MSIZE        Set this symbol to disable the use of40**                                _msize() on windows systems.  This might41**                                be necessary when compiling for Delphi,42**                                for example.43*/44#include "sqliteInt.h"45 46/*47** This version of the memory allocator is the default.  It is48** used when no other memory allocator is specified using compile-time49** macros.50*/51#ifdef SQLITE_SYSTEM_MALLOC52#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)53 54/*55** Use the zone allocator available on apple products unless the56** SQLITE_WITHOUT_ZONEMALLOC symbol is defined.57*/58#include <sys/sysctl.h>59#include <malloc/malloc.h>60#ifdef SQLITE_MIGHT_BE_SINGLE_CORE61#include <libkern/OSAtomic.h>62#endif /* SQLITE_MIGHT_BE_SINGLE_CORE */63static malloc_zone_t* _sqliteZone_;64#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))65#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));66#define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y))67#define SQLITE_MALLOCSIZE(x) \68        (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x))69 70#else /* if not __APPLE__ */71 72/*73** Use standard C library malloc and free on non-Apple systems.  74** Also used by Apple systems if SQLITE_WITHOUT_ZONEMALLOC is defined.75*/76#define SQLITE_MALLOC(x)             malloc(x)77#define SQLITE_FREE(x)               free(x)78#define SQLITE_REALLOC(x,y)          realloc((x),(y))79 80/*81** The malloc.h header file is needed for malloc_usable_size() function82** on some systems (e.g. Linux).83*/84#if HAVE_MALLOC_H && HAVE_MALLOC_USABLE_SIZE85#  define SQLITE_USE_MALLOC_H 186#  define SQLITE_USE_MALLOC_USABLE_SIZE 187/*88** The MSVCRT has malloc_usable_size(), but it is called _msize().  The89** use of _msize() is automatic, but can be disabled by compiling with90** -DSQLITE_WITHOUT_MSIZE.  Using the _msize() function also requires91** the malloc.h header file.92*/93#elif defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)94#  define SQLITE_USE_MALLOC_H95#  define SQLITE_USE_MSIZE96#endif97 98/*99** Include the malloc.h header file, if necessary.  Also set define macro100** SQLITE_MALLOCSIZE to the appropriate function name, which is _msize()101** for MSVC and malloc_usable_size() for most other systems (e.g. Linux).102** The memory size function can always be overridden manually by defining103** the macro SQLITE_MALLOCSIZE to the desired function name.104*/105#if defined(SQLITE_USE_MALLOC_H)106#  include <malloc.h>107#  if defined(SQLITE_USE_MALLOC_USABLE_SIZE)108#    if !defined(SQLITE_MALLOCSIZE)109#      define SQLITE_MALLOCSIZE(x)   malloc_usable_size(x)110#    endif111#  elif defined(SQLITE_USE_MSIZE)112#    if !defined(SQLITE_MALLOCSIZE)113#      define SQLITE_MALLOCSIZE      _msize114#    endif115#  endif116#endif /* defined(SQLITE_USE_MALLOC_H) */117 118#endif /* __APPLE__ or not __APPLE__ */119 120/*121** Like malloc(), but remember the size of the allocation122** so that we can find it later using sqlite3MemSize().123**124** For this low-level routine, we are guaranteed that nByte>0 because125** cases of nByte<=0 will be intercepted and dealt with by higher level126** routines.127*/128static void *sqlite3MemMalloc(int nByte){129#ifdef SQLITE_MALLOCSIZE130  void *p;131  testcase( ROUND8(nByte)==nByte );132  p = SQLITE_MALLOC( nByte );133  if( p==0 ){134    testcase( sqlite3GlobalConfig.xLog!=0 );135    sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);136  }137  return p;138#else139  sqlite3_int64 *p;140  assert( nByte>0 );141  testcase( ROUND8(nByte)!=nByte );142  p = SQLITE_MALLOC( nByte+8 );143  if( p ){144    p[0] = nByte;145    p++;146  }else{147    testcase( sqlite3GlobalConfig.xLog!=0 );148    sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);149  }150  return (void *)p;151#endif152}153 154/*155** Like free() but works for allocations obtained from sqlite3MemMalloc()156** or sqlite3MemRealloc().157**158** For this low-level routine, we already know that pPrior!=0 since159** cases where pPrior==0 will have been intercepted and dealt with160** by higher-level routines.161*/162static void sqlite3MemFree(void *pPrior){163#ifdef SQLITE_MALLOCSIZE164  SQLITE_FREE(pPrior);165#else166  sqlite3_int64 *p = (sqlite3_int64*)pPrior;167  assert( pPrior!=0 );168  p--;169  SQLITE_FREE(p);170#endif171}172 173/*174** Report the allocated size of a prior return from xMalloc()175** or xRealloc().176*/177static int sqlite3MemSize(void *pPrior){178#ifdef SQLITE_MALLOCSIZE179  assert( pPrior!=0 );180  return (int)SQLITE_MALLOCSIZE(pPrior);181#else182  sqlite3_int64 *p;183  assert( pPrior!=0 );184  p = (sqlite3_int64*)pPrior;185  p--;186  return (int)p[0];187#endif188}189 190/*191** Like realloc().  Resize an allocation previously obtained from192** sqlite3MemMalloc().193**194** For this low-level interface, we know that pPrior!=0.  Cases where195** pPrior==0 while have been intercepted by higher-level routine and196** redirected to xMalloc.  Similarly, we know that nByte>0 because197** cases where nByte<=0 will have been intercepted by higher-level198** routines and redirected to xFree.199*/200static void *sqlite3MemRealloc(void *pPrior, int nByte){201#ifdef SQLITE_MALLOCSIZE202  void *p = SQLITE_REALLOC(pPrior, nByte);203  if( p==0 ){204    testcase( sqlite3GlobalConfig.xLog!=0 );205    sqlite3_log(SQLITE_NOMEM,206      "failed memory resize %u to %u bytes",207      SQLITE_MALLOCSIZE(pPrior), nByte);208  }209  return p;210#else211  sqlite3_int64 *p = (sqlite3_int64*)pPrior;212  assert( pPrior!=0 && nByte>0 );213  assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */214  p--;215  p = SQLITE_REALLOC(p, nByte+8 );216  if( p ){217    p[0] = nByte;218    p++;219  }else{220    testcase( sqlite3GlobalConfig.xLog!=0 );221    sqlite3_log(SQLITE_NOMEM,222      "failed memory resize %u to %u bytes",223      sqlite3MemSize(pPrior), nByte);224  }225  return (void*)p;226#endif227}228 229/*230** Round up a request size to the next valid allocation size.231*/232static int sqlite3MemRoundup(int n){233  return ROUND8(n);234}235 236/*237** Initialize this module.238*/239static int sqlite3MemInit(void *NotUsed){240#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)241  int cpuCount;242  size_t len;243  if( _sqliteZone_ ){244    return SQLITE_OK;245  }246  len = sizeof(cpuCount);247  /* One usually wants to use hw.activecpu for MT decisions, but not here */248  sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0);249  if( cpuCount>1 ){250    /* defer MT decisions to system malloc */251    _sqliteZone_ = malloc_default_zone();252  }else{253    /* only 1 core, use our own zone to contention over global locks,254    ** e.g. we have our own dedicated locks */255    _sqliteZone_ = malloc_create_zone(4096, 0);256    malloc_set_zone_name(_sqliteZone_, "Sqlite_Heap");257  }258#endif /*  defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) */259  UNUSED_PARAMETER(NotUsed);260  return SQLITE_OK;261}262 263/*264** Deinitialize this module.265*/266static void sqlite3MemShutdown(void *NotUsed){267  UNUSED_PARAMETER(NotUsed);268  return;269}270 271/*272** This routine is the only routine in this file with external linkage.273**274** Populate the low-level memory allocation function pointers in275** sqlite3GlobalConfig.m with pointers to the routines in this file.276*/277void sqlite3MemSetDefault(void){278  static const sqlite3_mem_methods defaultMethods = {279     sqlite3MemMalloc,280     sqlite3MemFree,281     sqlite3MemRealloc,282     sqlite3MemSize,283     sqlite3MemRoundup,284     sqlite3MemInit,285     sqlite3MemShutdown,286     0287  };288  sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);289}290 291#endif /* SQLITE_SYSTEM_MALLOC */292