modernc.org/cc@v1.0.1/v2/testdata/_sqlite/src/mem1.c (about)

     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.  The content of
    19  ** this file is only used if SQLITE_SYSTEM_MALLOC is defined.  The
    20  ** SQLITE_SYSTEM_MALLOC macro is defined automatically if neither the
    21  ** SQLITE_MEMDEBUG nor the SQLITE_WIN32_MALLOC macros are defined.  The
    22  ** default configuration is to use memory allocation routines in this
    23  ** file.
    24  **
    25  ** C-preprocessor macro summary:
    26  **
    27  **    HAVE_MALLOC_USABLE_SIZE     The configure script sets this symbol if
    28  **                                the malloc_usable_size() interface exists
    29  **                                on the target platform.  Or, this symbol
    30  **                                can be set manually, if desired.
    31  **                                If an equivalent interface exists by
    32  **                                a different name, using a separate -D
    33  **                                option to rename it.
    34  **
    35  **    SQLITE_WITHOUT_ZONEMALLOC   Some older macs lack support for the zone
    36  **                                memory allocator.  Set this symbol to enable
    37  **                                building on older macs.
    38  **
    39  **    SQLITE_WITHOUT_MSIZE        Set this symbol to disable the use of
    40  **                                _msize() on windows systems.  This might
    41  **                                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 is
    48  ** used when no other memory allocator is specified using compile-time
    49  ** macros.
    50  */
    51  #ifdef SQLITE_SYSTEM_MALLOC
    52  #if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)
    53  
    54  /*
    55  ** Use the zone allocator available on apple products unless the
    56  ** SQLITE_WITHOUT_ZONEMALLOC symbol is defined.
    57  */
    58  #include <sys/sysctl.h>
    59  #include <malloc/malloc.h>
    60  #ifdef SQLITE_MIGHT_BE_SINGLE_CORE
    61  #include <libkern/OSAtomic.h>
    62  #endif /* SQLITE_MIGHT_BE_SINGLE_CORE */
    63  static 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() function
    82  ** on some systems (e.g. Linux).
    83  */
    84  #if HAVE_MALLOC_H && HAVE_MALLOC_USABLE_SIZE
    85  #  define SQLITE_USE_MALLOC_H 1
    86  #  define SQLITE_USE_MALLOC_USABLE_SIZE 1
    87  /*
    88  ** The MSVCRT has malloc_usable_size(), but it is called _msize().  The
    89  ** use of _msize() is automatic, but can be disabled by compiling with
    90  ** -DSQLITE_WITHOUT_MSIZE.  Using the _msize() function also requires
    91  ** the malloc.h header file.
    92  */
    93  #elif defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)
    94  #  define SQLITE_USE_MALLOC_H
    95  #  define SQLITE_USE_MSIZE
    96  #endif
    97  
    98  /*
    99  ** Include the malloc.h header file, if necessary.  Also set define macro
   100  ** 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 defining
   103  ** 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  #    endif
   111  #  elif defined(SQLITE_USE_MSIZE)
   112  #    if !defined(SQLITE_MALLOCSIZE)
   113  #      define SQLITE_MALLOCSIZE      _msize
   114  #    endif
   115  #  endif
   116  #endif /* defined(SQLITE_USE_MALLOC_H) */
   117  
   118  #endif /* __APPLE__ or not __APPLE__ */
   119  
   120  /*
   121  ** Like malloc(), but remember the size of the allocation
   122  ** so that we can find it later using sqlite3MemSize().
   123  **
   124  ** For this low-level routine, we are guaranteed that nByte>0 because
   125  ** cases of nByte<=0 will be intercepted and dealt with by higher level
   126  ** routines.
   127  */
   128  static void *sqlite3MemMalloc(int nByte){
   129  #ifdef SQLITE_MALLOCSIZE
   130    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  #else
   139    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  #endif
   152  }
   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 since
   159  ** cases where pPrior==0 will have been intecepted and dealt with
   160  ** by higher-level routines.
   161  */
   162  static void sqlite3MemFree(void *pPrior){
   163  #ifdef SQLITE_MALLOCSIZE
   164    SQLITE_FREE(pPrior);
   165  #else
   166    sqlite3_int64 *p = (sqlite3_int64*)pPrior;
   167    assert( pPrior!=0 );
   168    p--;
   169    SQLITE_FREE(p);
   170  #endif
   171  }
   172  
   173  /*
   174  ** Report the allocated size of a prior return from xMalloc()
   175  ** or xRealloc().
   176  */
   177  static int sqlite3MemSize(void *pPrior){
   178  #ifdef SQLITE_MALLOCSIZE
   179    assert( pPrior!=0 );
   180    return (int)SQLITE_MALLOCSIZE(pPrior);
   181  #else
   182    sqlite3_int64 *p;
   183    assert( pPrior!=0 );
   184    p = (sqlite3_int64*)pPrior;
   185    p--;
   186    return (int)p[0];
   187  #endif
   188  }
   189  
   190  /*
   191  ** Like realloc().  Resize an allocation previously obtained from
   192  ** sqlite3MemMalloc().
   193  **
   194  ** For this low-level interface, we know that pPrior!=0.  Cases where
   195  ** pPrior==0 while have been intercepted by higher-level routine and
   196  ** redirected to xMalloc.  Similarly, we know that nByte>0 because
   197  ** cases where nByte<=0 will have been intercepted by higher-level
   198  ** routines and redirected to xFree.
   199  */
   200  static void *sqlite3MemRealloc(void *pPrior, int nByte){
   201  #ifdef SQLITE_MALLOCSIZE
   202    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  #else
   211    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  #endif
   227  }
   228  
   229  /*
   230  ** Round up a request size to the next valid allocation size.
   231  */
   232  static int sqlite3MemRoundup(int n){
   233    return ROUND8(n);
   234  }
   235  
   236  /*
   237  ** Initialize this module.
   238  */
   239  static 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.acctivecpu 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  */
   266  static 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 in
   275  ** sqlite3GlobalConfig.m with pointers to the routines in this file.
   276  */
   277  void sqlite3MemSetDefault(void){
   278    static const sqlite3_mem_methods defaultMethods = {
   279       sqlite3MemMalloc,
   280       sqlite3MemFree,
   281       sqlite3MemRealloc,
   282       sqlite3MemSize,
   283       sqlite3MemRoundup,
   284       sqlite3MemInit,
   285       sqlite3MemShutdown,
   286       0
   287    };
   288    sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
   289  }
   290  
   291  #endif /* SQLITE_SYSTEM_MALLOC */