diff options
Diffstat (limited to 'src/malloc.c')
-rw-r--r-- | src/malloc.c | 60 |
1 files changed, 55 insertions, 5 deletions
diff --git a/src/malloc.c b/src/malloc.c index 5916ec251..3c567c9c0 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -12,7 +12,7 @@ ** ** Memory allocation functions used throughout sqlite. ** -** $Id: malloc.c,v 1.16 2008/06/14 16:56:22 drh Exp $ +** $Id: malloc.c,v 1.17 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> @@ -90,7 +90,8 @@ static struct { */ sqlite3_int64 nowUsed; /* Main memory currently in use */ sqlite3_int64 mxUsed; /* Highwater mark for nowUsed */ - int mxReq; /* maximum request size for main or page-cache mem */ + int mxReq; /* Max request size for ordinary mallocs */ + int mxTempReq; /* Max request size for xTemp mallocs */ } mem0; /* @@ -227,6 +228,55 @@ void *sqlite3_malloc(int n){ } /* +** Each thread may only have a single outstanding allocation from +** xTempMalloc(). We verify this constraint in the single-threaded +** case by setting tempAllocOut to 1 when an allocation +** is outstanding clearing it when the allocation is freed. +*/ +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) +static int tempAllocOut = 0; +#endif + + +/* +** Allocate memory that is to be used and released right away. +** This routine is similar to alloca() in that it is not intended +** for situations where the memory might be held long-term. This +** routine is intended to get memory to old large transient data +** structures that would not normally fit on the stack of an +** embedded processor. +*/ +void *sqlite3TempMalloc(int n){ + void *p; + assert( n>0 ); + if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){ + return 0; + } +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) + assert( tempAllocOut==0 ); + tempAllocOut = 1; +#endif + if( sqlite3Config.bMemstat ){ + sqlite3_mutex_enter(mem0.mutex); + if( n>mem0.mxTempReq ) mem0.mxTempReq = n; + p = sqlite3Config.m.xTempMalloc(n); + sqlite3_mutex_leave(mem0.mutex); + }else{ + p = sqlite3Config.m.xTempMalloc(n); + } + return p; +} +void sqlite3TempFree(void *p){ + if( p ){ +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) + assert( tempAllocOut==1 ); + tempAllocOut = 0; +#endif + sqlite3Config.m.xTempFree(p); + } +} + +/* ** Return the size of a memory allocation previously obtained from ** sqlite3Malloc() or sqlite3_malloc(). */ @@ -386,14 +436,14 @@ char *sqlite3StrDup(const char *z){ int n; if( z==0 ) return 0; n = strlen(z)+1; - zNew = sqlite3_malloc(n); + zNew = sqlite3Malloc(n); if( zNew ) memcpy(zNew, z, n); return zNew; } char *sqlite3StrNDup(const char *z, int n){ char *zNew; if( z==0 ) return 0; - zNew = sqlite3_malloc(n+1); + zNew = sqlite3Malloc(n+1); if( zNew ){ memcpy(zNew, z, n); zNew[n] = 0; @@ -437,7 +487,7 @@ void sqlite3SetString(char **pz, ...){ } va_end(ap); sqlite3_free(*pz); - *pz = zResult = sqlite3_malloc(nByte); + *pz = zResult = sqlite3Malloc(nByte); if( zResult==0 ){ return; } |