--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/engine/sqlite/src/mem1.cpp Thu Feb 25 14:29:19 2010 +0000
@@ -0,0 +1,232 @@
+/*
+** 2007 August 14
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains the C functions that implement a memory
+** allocation subsystem for use by SQLite.
+**
+** $Id: mem1.cpp 1282 2008-11-13 09:31:33Z LarsPson $
+*/
+
+/*
+** This version of the memory allocator is the default. It is
+** used when no other memory allocator is specified using compile-time
+** macros.
+*/
+#if !defined(SQLITE_MEMDEBUG) && !defined(SQLITE_MEMORY_SIZE) \
+ && !defined(SQLITE_MMAP_HEAP_SIZE)
+
+/*
+** We will eventually construct multiple memory allocation subsystems
+** suitable for use in various contexts:
+**
+** * Normal multi-threaded builds
+** * Normal single-threaded builds
+** * Debugging builds
+**
+** This initial version is suitable for use in normal multi-threaded
+** builds. We envision that alternative versions will be stored in
+** separate source files. #ifdefs will be used to select the code from
+** one of the various memN.c source files for use in any given build.
+*/
+#include "sqliteInt.h"
+
+/*
+** All of the static variables used by this module are collected
+** into a single structure named "mem". This is to keep the
+** static variables organized and to reduce namespace pollution
+** when this module is combined with other in the amalgamation.
+*/
+static struct {
+ /*
+ ** The alarm callback and its arguments. The mem.mutex lock will
+ ** be held while the callback is running. Recursive calls into
+ ** the memory subsystem are allowed, but no new callbacks will be
+ ** issued. The alarmBusy variable is set to prevent recursive
+ ** callbacks.
+ */
+ sqlite3_int64 alarmThreshold;
+ void (*alarmCallback)(void*, sqlite3_int64,int);
+ void *alarmArg;
+ int alarmBusy;
+
+ /*
+ ** Mutex to control access to the memory allocation subsystem.
+ */
+ sqlite3_mutex *mutex;
+
+ /*
+ ** Current allocation and high-water mark.
+ */
+ sqlite3_int64 nowUsed;
+ sqlite3_int64 mxUsed;
+
+
+} mem;
+
+/*
+** Enter the mutex mem.mutex. Allocate it if it is not already allocated.
+*/
+static void enterMem(void){
+ if( mem.mutex==0 ){
+ mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
+ }
+ sqlite3_mutex_enter(mem.mutex);
+}
+
+/*
+** Return the amount of memory currently checked out.
+*/
+EXPORT_C sqlite3_int64 sqlite3_memory_used(void){
+ sqlite3_int64 n;
+ enterMem();
+ n = mem.nowUsed;
+ sqlite3_mutex_leave(mem.mutex);
+ return n;
+}
+
+/*
+** Return the maximum amount of memory that has ever been
+** checked out since either the beginning of this process
+** or since the most recent reset.
+*/
+EXPORT_C sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
+ sqlite3_int64 n;
+ enterMem();
+ n = mem.mxUsed;
+ if( resetFlag ){
+ mem.mxUsed = mem.nowUsed;
+ }
+ sqlite3_mutex_leave(mem.mutex);
+ return n;
+}
+
+/*
+** Change the alarm callback
+*/
+EXPORT_C int sqlite3_memory_alarm(
+ void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
+ void *pArg,
+ sqlite3_int64 iThreshold
+){
+ enterMem();
+ mem.alarmCallback = xCallback;
+ mem.alarmArg = pArg;
+ mem.alarmThreshold = iThreshold;
+ sqlite3_mutex_leave(mem.mutex);
+ return SQLITE_OK;
+}
+
+/*
+** Trigger the alarm
+*/
+static void sqlite3MemsysAlarm(int nByte){
+ void (*xCallback)(void*,sqlite3_int64,int);
+ sqlite3_int64 nowUsed;
+ void *pArg;
+ if( mem.alarmCallback==0 || mem.alarmBusy ) return;
+ mem.alarmBusy = 1;
+ xCallback = mem.alarmCallback;
+ nowUsed = mem.nowUsed;
+ pArg = mem.alarmArg;
+ sqlite3_mutex_leave(mem.mutex);
+ xCallback(pArg, nowUsed, nByte);
+ sqlite3_mutex_enter(mem.mutex);
+ mem.alarmBusy = 0;
+}
+
+/*
+** Allocate nBytes of memory
+*/
+EXPORT_C void *sqlite3_malloc(int nBytes){
+ sqlite3_int64 *p = 0;
+ if( nBytes>0 ){
+ enterMem();
+ if( mem.alarmCallback!=0 && mem.nowUsed+nBytes>=mem.alarmThreshold ){
+ sqlite3MemsysAlarm(nBytes);
+ }
+ p = (sqlite3_int64*)malloc(nBytes+8);
+ if( p==0 ){
+ sqlite3MemsysAlarm(nBytes);
+ p = (sqlite3_int64*)malloc(nBytes+8);
+ }
+ if( p ){
+ p[0] = nBytes;
+ p++;
+ mem.nowUsed += nBytes;
+ if( mem.nowUsed>mem.mxUsed ){
+ mem.mxUsed = mem.nowUsed;
+ }
+ }
+ sqlite3_mutex_leave(mem.mutex);
+ }
+ return (void*)p;
+}
+
+/*
+** Free memory.
+*/
+EXPORT_C void sqlite3_free(void *pPrior){
+ sqlite3_int64 *p;
+ int nByte;
+ if( pPrior==0 ){
+ return;
+ }
+ assert( mem.mutex!=0 );
+ p = (sqlite3_int64*)pPrior;
+ p--;
+ nByte = (int)*p;
+ sqlite3_mutex_enter(mem.mutex);
+ mem.nowUsed -= nByte;
+ free(p);
+ sqlite3_mutex_leave(mem.mutex);
+}
+
+/*
+** Change the size of an existing memory allocation
+*/
+EXPORT_C void *sqlite3_realloc(void *pPrior, int nBytes){
+ int nOld;
+ sqlite3_int64 *p;
+ if( pPrior==0 ){
+ return sqlite3_malloc(nBytes);
+ }
+ if( nBytes<=0 ){
+ sqlite3_free(pPrior);
+ return 0;
+ }
+ p = (sqlite3_int64*)pPrior;
+ p--;
+ nOld = (int)p[0];
+ assert( mem.mutex!=0 );
+ sqlite3_mutex_enter(mem.mutex);
+ if( mem.nowUsed+nBytes-nOld>=mem.alarmThreshold ){
+ sqlite3MemsysAlarm(nBytes-nOld);
+ }
+ p = (sqlite3_int64*)realloc(p, nBytes+8);
+ if( p==0 ){
+ sqlite3MemsysAlarm(nBytes);
+ p = (sqlite3_int64*)pPrior;
+ p--;
+ p = (sqlite3_int64*)realloc(p, nBytes+8);
+ }
+ if( p ){
+ p[0] = nBytes;
+ p++;
+ mem.nowUsed += nBytes-nOld;
+ if( mem.nowUsed>mem.mxUsed ){
+ mem.mxUsed = mem.nowUsed;
+ }
+ }
+ sqlite3_mutex_leave(mem.mutex);
+ return (void*)p;
+}
+
+#endif /* !SQLITE_MEMDEBUG && !SQLITE_OMIT_MEMORY_ALLOCATION */