diff options
author | danielk1977 <danielk1977@noemail.net> | 2008-07-25 08:48:59 +0000 |
---|---|---|
committer | danielk1977 <danielk1977@noemail.net> | 2008-07-25 08:48:59 +0000 |
commit | 31fab4f30bfe449c7c80bb61d8d68956ad00fe45 (patch) | |
tree | 0c595c238d0c92d69635fb9b1338a25fe20ed96d /src | |
parent | 2abcd58f09da0d98118c4a2d2cb78f40dbc6a2ca (diff) | |
download | sqlite-31fab4f30bfe449c7c80bb61d8d68956ad00fe45.tar.gz sqlite-31fab4f30bfe449c7c80bb61d8d68956ad00fe45.zip |
Updates to mem6.c allocator. (CVS 5473)
FossilOrigin-Name: 43a4cae2acea33d1a17c0037516e9c27fb7e8e91
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 3 | ||||
-rw-r--r-- | src/mem1.c | 4 | ||||
-rw-r--r-- | src/mem2.c | 4 | ||||
-rw-r--r-- | src/mem6.c | 81 | ||||
-rw-r--r-- | src/sqlite.h.in | 5 | ||||
-rw-r--r-- | src/sqliteInt.h | 5 | ||||
-rw-r--r-- | src/test_malloc.c | 10 |
7 files changed, 84 insertions, 28 deletions
diff --git a/src/main.c b/src/main.c index 8cd1d6414..cf5587839 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.481 2008/07/24 08:20:40 danielk1977 Exp $ +** $Id: main.c,v 1.482 2008/07/25 08:49:00 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -269,6 +269,7 @@ int sqlite3_config(int op, ...){ #if defined(SQLITE_ENABLE_MEMSYS6) case SQLITE_CONFIG_CHUNKALLOC: { + sqlite3Config.nSmall = va_arg(ap, int); sqlite3Config.m = *sqlite3MemGetMemsys6(); break; } diff --git a/src/mem1.c b/src/mem1.c index 359ce5d8c..1a3a68eb0 100644 --- a/src/mem1.c +++ b/src/mem1.c @@ -17,7 +17,7 @@ ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. ** -** $Id: mem1.c,v 1.24 2008/07/24 08:20:40 danielk1977 Exp $ +** $Id: mem1.c,v 1.25 2008/07/25 08:49:00 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -120,7 +120,7 @@ static void sqlite3MemShutdown(void *NotUsed){ return; } -sqlite3_mem_methods *sqlite3MemGetDefault(void){ +const sqlite3_mem_methods *sqlite3MemGetDefault(void){ static const sqlite3_mem_methods defaultMethods = { sqlite3MemMalloc, sqlite3MemFree, diff --git a/src/mem2.c b/src/mem2.c index 33c8cfeff..f1425e8ce 100644 --- a/src/mem2.c +++ b/src/mem2.c @@ -19,7 +19,7 @@ ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. ** -** $Id: mem2.c,v 1.36 2008/07/24 23:34:07 drh Exp $ +** $Id: mem2.c,v 1.37 2008/07/25 08:49:00 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -324,7 +324,7 @@ static void *sqlite3MemRealloc(void *pPrior, int nByte){ } -sqlite3_mem_methods *sqlite3MemGetDefault(void){ +const sqlite3_mem_methods *sqlite3MemGetDefault(void){ static const sqlite3_mem_methods defaultMethods = { sqlite3MemMalloc, sqlite3MemFree, diff --git a/src/mem6.c b/src/mem6.c index bf1724c40..7903c08b3 100644 --- a/src/mem6.c +++ b/src/mem6.c @@ -10,19 +10,52 @@ ** ************************************************************************* ** -** $Id: mem6.c,v 1.2 2008/07/24 10:11:28 danielk1977 Exp $ +** This file contains an alternative memory allocation system for SQLite. +** This system is implemented as a wrapper around the default memory +** allocation system (usually the one found in mem1.c - system malloc). +** +** This system differentiates between requests for "small" allocations +** (by default those of 128 bytes or less) and "large" allocations (all +** others). The 256 byte threshhold is configurable at runtime. +** +** All requests for large allocations are passed through to the +** default memory allocation system. +** +** Requests for small allocations are met by allocating space within +** one or more larger "chunks" of memory obtained from the default +** memory allocation system. Chunks of memory are usually 64KB or +** larger. The algorithm used to manage space within each chunk is +** the same as that used by mem5.c. +** +** This strategy is designed to prevent the default memory allocation +** system (usually the system malloc) from suffering from heap +** fragmentation. On some systems, heap fragmentation can cause a +** significant real-time slowdown. +** +** $Id: mem6.c,v 1.3 2008/07/25 08:49:00 danielk1977 Exp $ */ #ifdef SQLITE_ENABLE_MEMSYS6 +#include "sqliteInt.h" + /* -** Maximum size of any allocation is ((1<<LOGMAX)*Mem6Chunk.nAtom). Since -** Mem6Chunk.nAtom is always at least 8, this is not really a practical -** limitation. +** Maximum size of any "small" allocation is ((1<<LOGMAX)*Mem6Chunk.nAtom). +** Mem6Chunk.nAtom is always at least 8, so this is not a practical +** limitation */ #define LOGMAX 30 -#include "sqliteInt.h" +/* +** Default value for the "small" allocation size threshold. +*/ +#define SMALL_MALLOC_DEFAULT_THRESHOLD 256 + +/* +** Minimum size for a memory chunk. +*/ +#define MIN_CHUNKSIZE (1<<16) + typedef struct Mem6Chunk Mem6Chunk; typedef struct Mem6Link Mem6Link; @@ -278,12 +311,9 @@ static Mem6Chunk *chunkInit(u8 *zChunk, int nChunk, int nMinAlloc){ struct Mem6Global { sqlite3_mem_methods parent; /* Used to allocate chunks */ - int nChunkSize; /* Size of each chunk, in bytes. */ int nMinAlloc; /* Minimum allowed allocation size */ - + int nThreshold; /* Allocs larger than this go to parent */ sqlite3_mutex *mutex; - - /* This data structure will be fixed... */ Mem6Chunk *pChunk; /* Singly linked list of all memory chunks */ } mem6; @@ -297,6 +327,22 @@ static void mem6Leave(void){ } /* +** Based on the number and size of the currently allocated chunks, return +** the size of the next chunk to allocate, in bytes. +*/ +static int nextChunkSize(void){ + int iTotal = 0; + Mem6Chunk *p; + for(p=mem6.pChunk; p; p=p->pNext){ + iTotal += mem6.parent.xSize((void *)p); + } + if( iTotal==0 ){ + iTotal = MIN_CHUNKSIZE; + } + return iTotal; +} + +/* ** The argument is a pointer that may or may not have been allocated from ** one of the Mem6Chunk objects managed within mem6. If it is, return ** a pointer to the owner chunk. If not, return 0. @@ -323,7 +369,7 @@ static void *memsys6Malloc(int nByte){ void *p = 0; mem6Enter(); - if( nByte>=mem6.nChunkSize/3 ){ + if( nByte>mem6.nThreshold ){ p = mem6.parent.xMalloc(nByte); }else{ for(pChunk=mem6.pChunk; !p && pChunk; pChunk=pChunk->pNext){ @@ -331,9 +377,10 @@ static void *memsys6Malloc(int nByte){ } if( !p ){ - p = mem6.parent.xMalloc(mem6.nChunkSize); + int iSize = nextChunkSize(); + p = mem6.parent.xMalloc(iSize); if( p ){ - pChunk = chunkInit((u8 *)p, mem6.nChunkSize, mem6.nMinAlloc); + pChunk = chunkInit((u8 *)p, iSize, mem6.nMinAlloc); pChunk->pNext = mem6.pChunk; mem6.pChunk = pChunk; p = chunkMalloc(pChunk, nByte); @@ -398,10 +445,12 @@ static int memsys6Roundup(int n){ static int memsys6Init(void *pCtx){ u8 bMemstat = sqlite3Config.bMemstat; mem6.parent = *sqlite3MemGetDefault(); - mem6.nChunkSize = (1<<16); mem6.nMinAlloc = 16; mem6.pChunk = 0; - + mem6.nThreshold = sqlite3Config.nSmall; + if( mem6.nThreshold<=0 ){ + mem6.nThreshold = SMALL_MALLOC_DEFAULT_THRESHOLD; + } if( !bMemstat ){ mem6.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); } @@ -419,6 +468,10 @@ static int memsys6Init(void *pCtx){ } static void memsys6Shutdown(void *pCtx){ + if( mem6.parent.xShutdown ){ + mem6.parent.xShutdown(mem6.parent.pAppData); + } + memset(&mem6, 0, sizeof(mem6)); } /* diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 3a7f1a220..246ba6ea8 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.378 2008/07/24 08:20:40 danielk1977 Exp $ +** @(#) $Id: sqlite.h.in,v 1.379 2008/07/25 08:49:00 danielk1977 Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -1157,8 +1157,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_CHUNKALLOC 12 /* nil */ +#define SQLITE_CONFIG_CHUNKALLOC 12 /* int threshold */ /* diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 28d6176d5..45cbdfdb6 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.744 2008/07/24 08:20:40 danielk1977 Exp $ +** @(#) $Id: sqliteInt.h,v 1.745 2008/07/25 08:49:00 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1789,6 +1789,7 @@ struct Sqlite3Config { int isInit; /* True after initialization has finished */ int isMallocInit; /* True after malloc is initialized */ sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */ + int nSmall; /* alloc size threshold used by mem6.c */ }; /* @@ -1841,7 +1842,7 @@ void sqlite3ScratchFree(void*); void *sqlite3PageMalloc(int); void sqlite3PageFree(void*); void sqlite3MemSetDefault(void); -sqlite3_mem_methods *sqlite3MemGetDefault(void); +const sqlite3_mem_methods *sqlite3MemGetDefault(void); const sqlite3_mem_methods *sqlite3MemGetMemsys5(void); const sqlite3_mem_methods *sqlite3MemGetMemsys3(void); const sqlite3_mem_methods *sqlite3MemGetMemsys6(void); diff --git a/src/test_malloc.c b/src/test_malloc.c index 30df0348f..ea5c2d6c7 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.39 2008/07/24 08:20:40 danielk1977 Exp $ +** $Id: test_malloc.c,v 1.40 2008/07/25 08:49:00 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -967,11 +967,13 @@ static int test_config_chunkalloc( Tcl_Obj *CONST objv[] ){ int rc; - if( objc!=1 ){ - Tcl_WrongNumArgs(interp, 1, objv, ""); + int nThreshold; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "THRESHOLD"); return TCL_ERROR; } - rc = sqlite3_config(SQLITE_CONFIG_CHUNKALLOC); + if( Tcl_GetIntFromObj(interp, objv[1], &nThreshold) ) return TCL_ERROR; + rc = sqlite3_config(SQLITE_CONFIG_CHUNKALLOC, nThreshold); Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_OK; } |