diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 8 | ||||
-rw-r--r-- | src/mem3.c | 84 | ||||
-rw-r--r-- | src/sqlite.h.in | 17 | ||||
-rw-r--r-- | src/sqliteInt.h | 3 | ||||
-rw-r--r-- | src/test_malloc.c | 36 |
5 files changed, 97 insertions, 51 deletions
diff --git a/src/main.c b/src/main.c index e5f6f6ee2..5f231f181 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.459 2008/06/24 19:02:55 danielk1977 Exp $ +** $Id: main.c,v 1.460 2008/06/25 10:34:35 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -149,11 +149,11 @@ int sqlite3_config(int op, ...){ sqlite3Config.bFullMutex = 1; break; } -#ifdef SQLITE_ENABLE_MEMPOOL - case SQLITE_CONFIG_MEMPOOL: { +#ifdef SQLITE_ENABLE_MEMSYS3 + case SQLITE_CONFIG_MEMSYS3: { u8 *pMem = va_arg(ap, u8*); int nMem = va_arg(ap, int); - rc = sqlite3MemSetMempool(pMem, nMem); + sqlite3MemSetMemsys3(pMem, nMem); break; } #endif diff --git a/src/mem3.c b/src/mem3.c index ef700f7ee..d2f8da927 100644 --- a/src/mem3.c +++ b/src/mem3.c @@ -13,25 +13,28 @@ ** allocation subsystem for use by SQLite. ** ** This version of the memory allocation subsystem omits all -** use of malloc(). All dynamically allocatable memory is -** contained in a static array, mem3.aPool[]. The size of this -** fixed memory pool is SQLITE_MEMORY_SIZE bytes. +** use of malloc(). The SQLite user supplies a block of memory +** before calling sqlite3_initialize() from which allocations +** are made and returned by the xMalloc() and xRealloc() +** implementations. Once sqlite3_initialize() has been called, +** the amount of memory available to SQLite is fixed and cannot +** be changed. ** -** This version of the memory allocation subsystem is used if -** and only if SQLITE_MEMORY_SIZE is defined. +** This version of the memory allocation subsystem is included +** in the build only if SQLITE_ENABLE_MEMSYS3 is defined. ** -** $Id: mem3.c,v 1.15 2008/06/24 19:02:55 danielk1977 Exp $ +** $Id: mem3.c,v 1.16 2008/06/25 10:34:35 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** This version of the memory allocator is only built into the library -** SQLITE_ENABLE_MEMPOOL is defined. Defining this symbol does not +** SQLITE_ENABLE_MEMSYS3 is defined. Defining this symbol does not ** mean that the library will use a memory-pool by default, just that ** it is available. The mempool allocator is activated by calling ** sqlite3_config(). */ -#ifdef SQLITE_ENABLE_MEMPOOL +#ifdef SQLITE_ENABLE_MEMSYS3 /* ** Maximum size (in Mem3Blocks) of a "small" chunk. @@ -347,8 +350,11 @@ static void memsys3Merge(u32 *pRoot){ /* ** Return a block of memory of at least nBytes in size. ** Return NULL if unable. +** +** This function assumes that the necessary mutexes, if any, are +** already held by the caller. Hence "Unsafe". */ -static void *memsys3Malloc(int nByte){ +static void *memsys3MallocUnsafe(int nByte){ u32 i; int nBlock; int toFree; @@ -426,8 +432,11 @@ static void *memsys3Malloc(int nByte){ /* ** Free an outstanding memory allocation. +** +** This function assumes that the necessary mutexes, if any, are +** already held by the caller. Hence "Unsafe". */ -void memsys3Free(void *pOld){ +void memsys3FreeUnsafe(void *pOld){ Mem3Block *p = (Mem3Block*)pOld; int i; u32 size, x; @@ -466,11 +475,11 @@ void memsys3Free(void *pOld){ /* ** Allocate nBytes of memory. */ -static void *mempoolMalloc(int nBytes){ +static void *memsys3Malloc(int nBytes){ sqlite3_int64 *p; assert( nBytes>0 ); /* malloc.c filters out 0 byte requests */ memsys3Enter(); - p = memsys3Malloc(nBytes); + p = memsys3MallocUnsafe(nBytes); memsys3Leave(); return (void*)p; } @@ -478,10 +487,10 @@ static void *mempoolMalloc(int nBytes){ /* ** Free memory. */ -void mempoolFree(void *pPrior){ +void memsys3Free(void *pPrior){ assert( pPrior ); memsys3Enter(); - memsys3Free(pPrior); + memsys3FreeUnsafe(pPrior); memsys3Leave(); } @@ -490,7 +499,7 @@ void mempoolFree(void *pPrior){ ** size returned omits the 8-byte header overhead. This only ** works for chunks that are currently checked out. */ -static int mempoolSize(void *p){ +static int memsys3Size(void *p){ Mem3Block *pBlock = (Mem3Block*)p; assert( pBlock ); assert( (pBlock[-1].u.hdr.size4x&1)!=0 ); @@ -500,7 +509,7 @@ static int mempoolSize(void *p){ /* ** Change the size of an existing memory allocation */ -void *mempoolRealloc(void *pPrior, int nBytes){ +void *memsys3Realloc(void *pPrior, int nBytes){ int nOld; void *p; if( pPrior==0 ){ @@ -510,19 +519,19 @@ void *mempoolRealloc(void *pPrior, int nBytes){ sqlite3_free(pPrior); return 0; } - nOld = mempoolSize(pPrior); + nOld = memsys3Size(pPrior); if( nBytes<=nOld && nBytes>=nOld-128 ){ return pPrior; } memsys3Enter(); - p = mempoolMalloc(nBytes); + p = memsys3MallocUnsafe(nBytes); if( p ){ if( nOld<nBytes ){ memcpy(p, pPrior, nOld); }else{ memcpy(p, pPrior, nBytes); } - mempoolFree(pPrior); + memsys3FreeUnsafe(pPrior); } memsys3Leave(); return p; @@ -531,22 +540,21 @@ void *mempoolRealloc(void *pPrior, int nBytes){ /* ** Round up a request size to the next valid allocation size. */ -static int mempoolRoundup(int n){ - /* TODO: Fix me */ - return n; +static int memsys3Roundup(int n){ + return (n+7) & ~7; } /* ** Initialize this module. */ -static int mempoolInit(void *NotUsed){ +static int memsys3Init(void *NotUsed){ return SQLITE_OK; } /* ** Deinitialize this module. */ -static void mempoolShutdown(void *NotUsed){ +static void memsys3Shutdown(void *NotUsed){ return; } @@ -556,9 +564,8 @@ static void mempoolShutdown(void *NotUsed){ ** Open the file indicated and write a log of all unfreed memory ** allocations into that log. */ -#if 0 -void sqlite3MemdebugDump(const char *zFilename){ #ifdef SQLITE_DEBUG +void sqlite3Memsys3Dump(const char *zFilename){ FILE *out; int i, j; u32 size; @@ -574,7 +581,7 @@ void sqlite3MemdebugDump(const char *zFilename){ } memsys3Enter(); fprintf(out, "CHUNKS:\n"); - for(i=1; i<=SQLITE_MEMORY_SIZE/8; i+=size/4){ + for(i=1; i<=mem3.nPool; i+=size/4){ size = mem3.aPool[i-1].u.hdr.size4x; if( size/4<=1 ){ fprintf(out, "%p size error\n", &mem3.aPool[i]); @@ -617,15 +624,14 @@ void sqlite3MemdebugDump(const char *zFilename){ fprintf(out, "\n"); } fprintf(out, "master=%d\n", mem3.iMaster); - fprintf(out, "nowUsed=%d\n", SQLITE_MEMORY_SIZE - mem3.szMaster*8); - fprintf(out, "mxUsed=%d\n", SQLITE_MEMORY_SIZE - mem3.mnMaster*8); + fprintf(out, "nowUsed=%d\n", mem3.nPool*8 - mem3.szMaster*8); + fprintf(out, "mxUsed=%d\n", mem3.nPool*8 - mem3.mnMaster*8); sqlite3_mutex_leave(mem3.mutex); if( out==stdout ){ fflush(stdout); }else{ fclose(out); } -#endif } #endif @@ -640,15 +646,15 @@ void sqlite3MemdebugDump(const char *zFilename){ ** This routine is only called by sqlite3_config(), and therefore ** is not required to be threadsafe (it is not). */ -void sqlite3MemSetMempool(u8 *pBlock, int nBlock){ +void sqlite3MemSetMemsys3(u8 *pBlock, int nBlock){ static const sqlite3_mem_methods mempoolMethods = { - mempoolMalloc, - mempoolFree, - mempoolRealloc, - mempoolSize, - mempoolRoundup, - mempoolInit, - mempoolShutdown, + memsys3Malloc, + memsys3Free, + memsys3Realloc, + memsys3Size, + memsys3Roundup, + memsys3Init, + memsys3Shutdown, 0 }; @@ -669,4 +675,4 @@ void sqlite3MemSetMempool(u8 *pBlock, int nBlock){ mem3.aPool[mem3.nPool].u.hdr.size4x = 1; } -#endif /* SQLITE_MEMPOOL_MALLOC */ +#endif /* SQLITE_ENABLE_MEMSYS3 */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 316dc1674..dd1557f65 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -30,7 +30,7 @@ ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** -** @(#) $Id: sqlite.h.in,v 1.355 2008/06/24 19:02:55 danielk1977 Exp $ +** @(#) $Id: sqlite.h.in,v 1.356 2008/06/25 10:34:35 danielk1977 Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -1102,6 +1102,19 @@ struct sqlite3_mem_methods { ** routines with a wrapper used to track mutex usage for performance ** profiling or testing, for example.</dd> ** +** <dt>SQLITE_CONFIG_MEMSYS3</dt> +** <dd>This option is only available if SQLite is compiled with the +** SQLITE_ENABLE_MEMSYS3 symbol defined. If available, then it is used +** to install an alternative set of built-in memory allocation routines +** known as the "memsys3" allocator (in the same way as SQLITE_CONFIG_MALLOC +** may be used to install an external set of memory allocation routines). +** This options must be passed two arguments, a pointer to a large blob of +** allocated memory (type char*) and the size of the block of memory in bytes +** (type int). The memsys3 allocator manages this block of memory and uses +** it to satisfy all requests for dynamic memory made by the library. The +** caller must ensure that the block of memory remains valid for as long +** as the memsys3 allocator is in use.</dd> +** ** </dl> */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ @@ -1115,7 +1128,7 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ #define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ #define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ -#define SQLITE_CONFIG_MEMPOOL 12 /* u8*, int */ +#define SQLITE_CONFIG_MEMSYS3 12 /* u8*, int */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes {F12200} diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 5f5ec1792..7b94f368c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.726 2008/06/24 12:46:31 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.727 2008/06/25 10:34:35 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1803,6 +1803,7 @@ void sqlite3ScratchFree(void*); void *sqlite3PageMalloc(int); void sqlite3PageFree(void*); void sqlite3MemSetDefault(void); +void sqlite3MemSetMemsys3(u8 *pBlock, int nBlock); void sqlite3BenignMallocHooks(void (*)(void), void (*)(void)); #ifndef SQLITE_MUTEX_NOOP diff --git a/src/test_malloc.c b/src/test_malloc.c index b0762d7ab..95b44ac5f 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -13,7 +13,7 @@ ** This file contains code used to implement test interfaces to the ** memory allocation subsystem. ** -** $Id: test_malloc.c,v 1.29 2008/06/24 19:02:55 danielk1977 Exp $ +** $Id: test_malloc.c,v 1.30 2008/06/25 10:34:35 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -931,10 +931,10 @@ static int test_config_pagecache( } /* -** Usage: sqlite3_config_mempool NBYTE +** Usage: sqlite3_config_memsys3 NBYTE ** */ -static int test_config_mempool( +static int test_config_memsys3( void * clientData, Tcl_Interp *interp, int objc, @@ -956,13 +956,38 @@ static int test_config_mempool( if( sz>sizeof(buf) ){ sz = sizeof(buf); } - rc = sqlite3_config(SQLITE_CONFIG_MEMPOOL, buf, sz); + rc = sqlite3_config(SQLITE_CONFIG_MEMSYS3, buf, sz); } Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE); return TCL_OK; } /* +** Usage: sqlite3_dump_memsys3 FILENAME +** +** Write a summary of unfreed memsys3 allocations to FILENAME. +*/ +static int test_dump_memsys3( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); + return TCL_ERROR; + } +#if defined(SQLITE_MEMDEBUG) || defined(SQLITE_MEMORY_SIZE) \ + || defined(SQLITE_POW2_MEMORY_SIZE) + { + extern void sqlite3Memsys3Dump(const char*); + sqlite3Memsys3Dump(Tcl_GetString(objv[1])); + } +#endif + return TCL_OK; +} + +/* ** Usage: sqlite3_status OPCODE RESETFLAG ** ** Return a list of three elements which are the sqlite3_status() return @@ -1061,7 +1086,8 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){ { "sqlite3_memdebug_log", test_memdebug_log }, { "sqlite3_config_scratch", test_config_scratch }, { "sqlite3_config_pagecache", test_config_pagecache }, - { "sqlite3_config_mempool", test_config_mempool }, + { "sqlite3_config_memsys3", test_config_memsys3 }, + { "sqlite3_dump_memsys3", test_dump_memsys3 }, { "sqlite3_status", test_status }, { "install_malloc_faultsim", test_install_malloc_faultsim }, }; |