mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Continuing progress on the new memory allocation subsystem. Added the
sqlite3_mem_methods structure for defining new memory allocators at run-time. (CVS 5219) FossilOrigin-Name: f00305f4cd2f487f660f34a21c1c24a0b37c7275
This commit is contained in:
26
manifest
26
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Progress\stoward\simplementation\sof\ssqlite3_config()\sand\sa\srework\sof\sthe\nmutex\sand\smemory\sallocation\ssubsystems.\s\sThis\sis\san\sincremental\scheck-in.\s(CVS\s5218)
|
C Continuing\sprogress\son\sthe\snew\smemory\sallocation\ssubsystem.\s\sAdded\sthe\nsqlite3_mem_methods\sstructure\sfor\sdefining\snew\smemory\sallocators\sat\nrun-time.\s(CVS\s5219)
|
||||||
D 2008-06-13T18:24:27
|
D 2008-06-14T16:56:22
|
||||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||||
F Makefile.in dc5608df93faf4406cfd7a1c8ed9ab93d8bfbfd5
|
F Makefile.in dc5608df93faf4406cfd7a1c8ed9ab93d8bfbfd5
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -107,7 +107,7 @@ F src/delete.c d3fc5987f2eb88f7b9549d58a5dfea079a83fe8b
|
|||||||
F src/expr.c ecb3b23d3543427cba3e2ac12a6c6ae4bb20d39b
|
F src/expr.c ecb3b23d3543427cba3e2ac12a6c6ae4bb20d39b
|
||||||
F src/fault.c 1f6177188edb00641673e462f3fab8cba9f7422b
|
F src/fault.c 1f6177188edb00641673e462f3fab8cba9f7422b
|
||||||
F src/func.c 77a910a1ca7613d291fd0b5cba3be14c02f0dce0
|
F src/func.c 77a910a1ca7613d291fd0b5cba3be14c02f0dce0
|
||||||
F src/global.c 8a5c66b6e61c38072c697179dbc2d708e39ddc96
|
F src/global.c 2304cfa3288763bd2fed10caf8c6fbaa2b383f4e
|
||||||
F src/hash.c fd8cb06fb54c2fe7d48c9195792059a2e5be8b70
|
F src/hash.c fd8cb06fb54c2fe7d48c9195792059a2e5be8b70
|
||||||
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
|
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
|
||||||
F src/hwtime.h 745961687a65ef8918cd551c02e5ccb4b8e772de
|
F src/hwtime.h 745961687a65ef8918cd551c02e5ccb4b8e772de
|
||||||
@@ -115,15 +115,15 @@ F src/insert.c c2ead6c36566de8e3f130e7ab1431723a269d5d7
|
|||||||
F src/journal.c cffd2cd214e58c0e99c3ff632b3bee6c7cbb260e
|
F src/journal.c cffd2cd214e58c0e99c3ff632b3bee6c7cbb260e
|
||||||
F src/legacy.c 8f5a2b25d9673b4004287cf2bf51dbf7d0738406
|
F src/legacy.c 8f5a2b25d9673b4004287cf2bf51dbf7d0738406
|
||||||
F src/loadext.c f99a75534a53e281fa2461239ee4a4b4bf6ad564
|
F src/loadext.c f99a75534a53e281fa2461239ee4a4b4bf6ad564
|
||||||
F src/main.c 88caac737f4bdc646c7b298ebca867e9f3828208
|
F src/main.c 4540ec2c0ba99a0dcb8bd114f733007958c6258e
|
||||||
F src/malloc.c 12c1ae98ef1eff34b13c9eb526e0b7b479e1e820
|
F src/malloc.c ed5c36588992e63ce5dccdfeb3c8071b8fb34e17
|
||||||
F src/md5.c 008216bbb5d34c6fbab5357aa68575ad8a31516a
|
F src/md5.c 008216bbb5d34c6fbab5357aa68575ad8a31516a
|
||||||
F src/mem1.c 18ca1e2543252ce13cd9c1ba67853b2d8fece3dd
|
F src/mem1.c 9ac005ab606a58ffe32e40edd7526375be82a008
|
||||||
F src/mem2.c cb99d152253ae11cc2ccc4073611925e81c2212d
|
F src/mem2.c 10df776854bee610d5228e6184aaf3bd19f6e542
|
||||||
F src/mem3.c 617c2e2a72a10ecc5c01af14efc8c2596d2c2e87
|
F src/mem3.c 617c2e2a72a10ecc5c01af14efc8c2596d2c2e87
|
||||||
F src/mem4.c 45c328ec6dcb7e8d319cb383615b5fe547ca5409
|
F src/mem4.c 45c328ec6dcb7e8d319cb383615b5fe547ca5409
|
||||||
F src/mem5.c 3d2ff00c6e3bc37f5d82cd82e1a123b246fb7b39
|
F src/mem5.c 3d2ff00c6e3bc37f5d82cd82e1a123b246fb7b39
|
||||||
F src/mutex.c 1ff43a9f9a8e5a0d98ffccd77f56859d9fd9ffcf
|
F src/mutex.c 639881f679d75b30813536ddf9224154321c31fb
|
||||||
F src/mutex.h 91292a8351b5844f7d622b0da83df4e651a8f40b
|
F src/mutex.h 91292a8351b5844f7d622b0da83df4e651a8f40b
|
||||||
F src/mutex_os2.c b8c1231319e966875f251a7ec137bea353546b87
|
F src/mutex_os2.c b8c1231319e966875f251a7ec137bea353546b87
|
||||||
F src/mutex_unix.c 28588d08a2221623d66655e536880003fd5234d6
|
F src/mutex_unix.c 28588d08a2221623d66655e536880003fd5234d6
|
||||||
@@ -143,9 +143,9 @@ F src/printf.c f2d4f6c5b0ec24b643e85fe60258adad8b1f6acc
|
|||||||
F src/random.c 2b2db2de4ab491f5a14d3480466f8f4b5a5db74a
|
F src/random.c 2b2db2de4ab491f5a14d3480466f8f4b5a5db74a
|
||||||
F src/select.c 669687459e7d0193c89de06c5dbed55b4a41191c
|
F src/select.c 669687459e7d0193c89de06c5dbed55b4a41191c
|
||||||
F src/shell.c a12ea645271b7876c8f080146f48e20b00d367ec
|
F src/shell.c a12ea645271b7876c8f080146f48e20b00d367ec
|
||||||
F src/sqlite.h.in 487f5490a9677ef0c105c21a9595bb587be1da6a
|
F src/sqlite.h.in 0995188c694b36d041424e1b65b6e01d1802c70b
|
||||||
F src/sqlite3ext.h faacd0e6a81aabee0861c6d7883c9172e74ef5b3
|
F src/sqlite3ext.h faacd0e6a81aabee0861c6d7883c9172e74ef5b3
|
||||||
F src/sqliteInt.h c7b8bfb55381f62962eafd9826846c9e6e8bd429
|
F src/sqliteInt.h cd66968455ee85b1ffed33bb241cbf30fe760d32
|
||||||
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
|
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
|
||||||
F src/table.c 1fa8f8113ac9cbc09ae4801c6d2a7f0af82c5822
|
F src/table.c 1fa8f8113ac9cbc09ae4801c6d2a7f0af82c5822
|
||||||
F src/tclsqlite.c c57e740e30bd6dda678796eed62c7f0e64689834
|
F src/tclsqlite.c c57e740e30bd6dda678796eed62c7f0e64689834
|
||||||
@@ -594,7 +594,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P e93079be83a9df7328d9b910fcbdb762be7ec815
|
P a03c5af115889f477e17187a198a7d2d40bc76bf
|
||||||
R b8763d642b06205a0aac83d31a5eaad0
|
R 7a7d2d9fd4f0061599821d0212d56ac9
|
||||||
U drh
|
U drh
|
||||||
Z 7798430e342a4a876c2baf52ecfbbead
|
Z 3478c8b21bc53c2ad4322f8aef50d224
|
||||||
|
@@ -1 +1 @@
|
|||||||
a03c5af115889f477e17187a198a7d2d40bc76bf
|
f00305f4cd2f487f660f34a21c1c24a0b37c7275
|
@@ -12,7 +12,7 @@
|
|||||||
**
|
**
|
||||||
** This file contains definitions of global variables and contants.
|
** This file contains definitions of global variables and contants.
|
||||||
**
|
**
|
||||||
** $Id: global.c,v 1.1 2008/06/13 18:24:27 drh Exp $
|
** $Id: global.c,v 1.2 2008/06/14 16:56:22 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -66,4 +66,4 @@ const unsigned char sqlite3UpperToLower[] = {
|
|||||||
** The following singleton contains the global configuration for
|
** The following singleton contains the global configuration for
|
||||||
** the SQLite library.
|
** the SQLite library.
|
||||||
*/
|
*/
|
||||||
struct Sqlite3Config sqlite3Config;
|
struct Sqlite3Config sqlite3Config = { 1, 1, 1, };
|
||||||
|
11
src/main.c
11
src/main.c
@@ -14,7 +14,7 @@
|
|||||||
** other files are for internal use by SQLite and should not be
|
** other files are for internal use by SQLite and should not be
|
||||||
** accessed by users of the library.
|
** accessed by users of the library.
|
||||||
**
|
**
|
||||||
** $Id: main.c,v 1.443 2008/06/13 18:24:27 drh Exp $
|
** $Id: main.c,v 1.444 2008/06/14 16:56:22 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -103,6 +103,7 @@ int sqlite3_initialize(void){
|
|||||||
*/
|
*/
|
||||||
int sqlite3_shutdown(void){
|
int sqlite3_shutdown(void){
|
||||||
sqlite3_os_end();
|
sqlite3_os_end();
|
||||||
|
sqlite3MallocEnd();
|
||||||
sqlite3_mutex_end();
|
sqlite3_mutex_end();
|
||||||
sqlite3FullInit = 0;
|
sqlite3FullInit = 0;
|
||||||
sqlite3IsInit = 0;
|
sqlite3IsInit = 0;
|
||||||
@@ -149,14 +150,10 @@ int sqlite3_config(int op, ...){
|
|||||||
}
|
}
|
||||||
case SQLITE_CONFIG_MALLOC: {
|
case SQLITE_CONFIG_MALLOC: {
|
||||||
/* Specify an alternative malloc implementation */
|
/* Specify an alternative malloc implementation */
|
||||||
sqlite3Config.xMalloc = va_arg(ap, void*(*)(int));
|
sqlite3Config.m = *va_arg(ap, sqlite3_mem_methods*);
|
||||||
sqlite3Config.xFree = va_arg(ap, void(*)(void*));
|
|
||||||
sqlite3Config.xRealloc = va_arg(ap, void*(*)(void*,int));
|
|
||||||
sqlite3Config.xMemsize = va_arg(ap, int(*)(void*));
|
|
||||||
sqlite3Config.xRoundup = va_arg(ap, int(*)(int));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLITE_CONFIG_MEMSTATS: {
|
case SQLITE_CONFIG_MEMSTATUS: {
|
||||||
/* Enable or disable the malloc status collection */
|
/* Enable or disable the malloc status collection */
|
||||||
sqlite3Config.bMemstat = va_arg(ap, int);
|
sqlite3Config.bMemstat = va_arg(ap, int);
|
||||||
break;
|
break;
|
||||||
|
254
src/malloc.c
254
src/malloc.c
@@ -9,10 +9,10 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
|
**
|
||||||
** Memory allocation functions used throughout sqlite.
|
** 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.15 2008/03/26 18:34:43 danielk1977 Exp $
|
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@@ -67,12 +67,252 @@ int sqlite3_release_memory(int n){
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** State information local to the memory allocation subsystem.
|
||||||
|
*/
|
||||||
|
static struct {
|
||||||
|
sqlite3_mutex *mutex; /* Mutex to serialize access */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The alarm callback and its arguments. The mem0.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;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Performance statistics
|
||||||
|
*/
|
||||||
|
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 */
|
||||||
|
} mem0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Initialize the memory allocation subsystem.
|
||||||
|
*/
|
||||||
|
int sqlite3MallocInit(void){
|
||||||
|
if( sqlite3Config.m.xMalloc==0 ){
|
||||||
|
sqlite3MemSetDefault();
|
||||||
|
}
|
||||||
|
memset(&mem0, 0, sizeof(mem0));
|
||||||
|
if( sqlite3Config.bMemstat && sqlite3Config.bCoreMutex ){
|
||||||
|
mem0.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
|
||||||
|
}
|
||||||
|
return sqlite3Config.m.xInit(sqlite3Config.m.pAppData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Deinitialize the memory allocation subsystem.
|
||||||
|
*/
|
||||||
|
void sqlite3MallocEnd(void){
|
||||||
|
sqlite3Config.m.xShutdown(sqlite3Config.m.pAppData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return the amount of memory currently checked out.
|
||||||
|
*/
|
||||||
|
sqlite3_int64 sqlite3_memory_used(void){
|
||||||
|
sqlite3_int64 n;
|
||||||
|
sqlite3_mutex_enter(mem0.mutex);
|
||||||
|
n = mem0.nowUsed;
|
||||||
|
sqlite3_mutex_leave(mem0.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.
|
||||||
|
*/
|
||||||
|
sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
|
||||||
|
sqlite3_int64 n;
|
||||||
|
sqlite3_mutex_enter(mem0.mutex);
|
||||||
|
n = mem0.mxUsed;
|
||||||
|
if( resetFlag ){
|
||||||
|
mem0.mxUsed = mem0.nowUsed;
|
||||||
|
}
|
||||||
|
sqlite3_mutex_leave(mem0.mutex);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Change the alarm callback
|
||||||
|
*/
|
||||||
|
int sqlite3_memory_alarm(
|
||||||
|
void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
|
||||||
|
void *pArg,
|
||||||
|
sqlite3_int64 iThreshold
|
||||||
|
){
|
||||||
|
sqlite3_mutex_enter(mem0.mutex);
|
||||||
|
mem0.alarmCallback = xCallback;
|
||||||
|
mem0.alarmArg = pArg;
|
||||||
|
mem0.alarmThreshold = iThreshold;
|
||||||
|
sqlite3_mutex_leave(mem0.mutex);
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Trigger the alarm
|
||||||
|
*/
|
||||||
|
static void sqlite3MallocAlarm(int nByte){
|
||||||
|
void (*xCallback)(void*,sqlite3_int64,int);
|
||||||
|
sqlite3_int64 nowUsed;
|
||||||
|
void *pArg;
|
||||||
|
if( mem0.alarmCallback==0 || mem0.alarmBusy ) return;
|
||||||
|
mem0.alarmBusy = 1;
|
||||||
|
xCallback = mem0.alarmCallback;
|
||||||
|
nowUsed = mem0.nowUsed;
|
||||||
|
pArg = mem0.alarmArg;
|
||||||
|
sqlite3_mutex_leave(mem0.mutex);
|
||||||
|
xCallback(pArg, nowUsed, nByte);
|
||||||
|
sqlite3_mutex_enter(mem0.mutex);
|
||||||
|
mem0.alarmBusy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Allocate memory. This routine is like sqlite3_malloc() except that it
|
||||||
|
** assumes the memory subsystem has already been initialized.
|
||||||
|
*/
|
||||||
|
void *sqlite3Malloc(int n){
|
||||||
|
void *p;
|
||||||
|
int nFull;
|
||||||
|
if( n<=0 ){
|
||||||
|
return 0;
|
||||||
|
}else if( sqlite3Config.bMemstat ){
|
||||||
|
nFull = sqlite3Config.m.xRoundup(n);
|
||||||
|
sqlite3_mutex_enter(mem0.mutex);
|
||||||
|
if( n>mem0.mxReq ) mem0.mxReq = n;
|
||||||
|
if( mem0.alarmCallback!=0 && mem0.nowUsed+nFull>=mem0.alarmThreshold ){
|
||||||
|
sqlite3MallocAlarm(nFull);
|
||||||
|
}
|
||||||
|
if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){
|
||||||
|
p = 0;
|
||||||
|
}else{
|
||||||
|
p = sqlite3Config.m.xMalloc(nFull);
|
||||||
|
if( p==0 ){
|
||||||
|
sqlite3MallocAlarm(nFull);
|
||||||
|
p = malloc(nFull);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( p ){
|
||||||
|
mem0.nowUsed += nFull;
|
||||||
|
if( mem0.nowUsed>mem0.mxUsed ){
|
||||||
|
mem0.mxUsed = mem0.nowUsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sqlite3_mutex_leave(mem0.mutex);
|
||||||
|
}else{
|
||||||
|
p = sqlite3Config.m.xMalloc(n);
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This version of the memory allocation is for use by the application.
|
||||||
|
** First make sure the memory subsystem is initialized, then do the
|
||||||
|
** allocation.
|
||||||
|
*/
|
||||||
|
void *sqlite3_malloc(int n){
|
||||||
|
#ifndef SQLITE_OMIT_AUTOINIT
|
||||||
|
if( sqlite3_initialize() ) return 0;
|
||||||
|
#endif
|
||||||
|
return sqlite3Malloc(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return the size of a memory allocation previously obtained from
|
||||||
|
** sqlite3Malloc() or sqlite3_malloc().
|
||||||
|
*/
|
||||||
|
int sqlite3MallocSize(void *p){
|
||||||
|
return sqlite3Config.m.xSize(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Free memory previously obtained from sqlite3Malloc().
|
||||||
|
*/
|
||||||
|
void sqlite3_free(void *p){
|
||||||
|
if( p==0 ) return;
|
||||||
|
if( sqlite3Config.bMemstat ){
|
||||||
|
sqlite3_mutex_enter(mem0.mutex);
|
||||||
|
mem0.nowUsed -= sqlite3MallocSize(p);
|
||||||
|
sqlite3Config.m.xFree(p);
|
||||||
|
sqlite3_mutex_leave(mem0.mutex);
|
||||||
|
}else{
|
||||||
|
sqlite3Config.m.xFree(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Change the size of an existing memory allocation
|
||||||
|
*/
|
||||||
|
void *sqlite3Realloc(void *pOld, int nBytes){
|
||||||
|
int nOld, nNew;
|
||||||
|
void *pNew;
|
||||||
|
if( pOld==0 ){
|
||||||
|
return sqlite3Malloc(nBytes);
|
||||||
|
}
|
||||||
|
if( nBytes<=0 ){
|
||||||
|
sqlite3_free(pOld);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
nOld = sqlite3MallocSize(pOld);
|
||||||
|
if( sqlite3Config.bMemstat ){
|
||||||
|
sqlite3_mutex_enter(mem0.mutex);
|
||||||
|
if( nBytes>mem0.mxReq ) mem0.mxReq = nBytes;
|
||||||
|
nNew = sqlite3Config.m.xRoundup(nBytes);
|
||||||
|
if( nOld==nNew ){
|
||||||
|
pNew = pOld;
|
||||||
|
}else{
|
||||||
|
if( mem0.nowUsed+nNew-nOld>=mem0.alarmThreshold ){
|
||||||
|
sqlite3MallocAlarm(nNew-nOld);
|
||||||
|
}
|
||||||
|
if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){
|
||||||
|
pNew = 0;
|
||||||
|
}else{
|
||||||
|
pNew = sqlite3Config.m.xRealloc(pOld, nNew);
|
||||||
|
if( pNew==0 ){
|
||||||
|
sqlite3MallocAlarm(nBytes);
|
||||||
|
pNew = sqlite3Config.m.xRealloc(pOld, nNew);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( pNew ){
|
||||||
|
mem0.nowUsed += nNew-nOld;
|
||||||
|
if( mem0.nowUsed>mem0.mxUsed ){
|
||||||
|
mem0.mxUsed = mem0.nowUsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sqlite3_mutex_leave(mem0.mutex);
|
||||||
|
}else{
|
||||||
|
pNew = sqlite3Config.m.xRealloc(pOld, nBytes);
|
||||||
|
}
|
||||||
|
return pNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The public interface to sqlite3Realloc. Make sure that the memory
|
||||||
|
** subsystem is initialized prior to invoking sqliteRealloc.
|
||||||
|
*/
|
||||||
|
void *sqlite3_realloc(void *pOld, int n){
|
||||||
|
#ifndef SQLITE_OMIT_AUTOINIT
|
||||||
|
if( sqlite3_initialize() ) return 0;
|
||||||
|
#endif
|
||||||
|
return sqlite3Realloc(pOld, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Allocate and zero memory.
|
** Allocate and zero memory.
|
||||||
*/
|
*/
|
||||||
void *sqlite3MallocZero(unsigned n){
|
void *sqlite3MallocZero(int n){
|
||||||
void *p = sqlite3_malloc(n);
|
void *p = sqlite3Malloc(n);
|
||||||
if( p ){
|
if( p ){
|
||||||
memset(p, 0, n);
|
memset(p, 0, n);
|
||||||
}
|
}
|
||||||
@@ -83,7 +323,7 @@ void *sqlite3MallocZero(unsigned n){
|
|||||||
** Allocate and zero memory. If the allocation fails, make
|
** Allocate and zero memory. If the allocation fails, make
|
||||||
** the mallocFailed flag in the connection pointer.
|
** the mallocFailed flag in the connection pointer.
|
||||||
*/
|
*/
|
||||||
void *sqlite3DbMallocZero(sqlite3 *db, unsigned n){
|
void *sqlite3DbMallocZero(sqlite3 *db, int n){
|
||||||
void *p = sqlite3DbMallocRaw(db, n);
|
void *p = sqlite3DbMallocRaw(db, n);
|
||||||
if( p ){
|
if( p ){
|
||||||
memset(p, 0, n);
|
memset(p, 0, n);
|
||||||
@@ -95,10 +335,10 @@ void *sqlite3DbMallocZero(sqlite3 *db, unsigned n){
|
|||||||
** Allocate and zero memory. If the allocation fails, make
|
** Allocate and zero memory. If the allocation fails, make
|
||||||
** the mallocFailed flag in the connection pointer.
|
** the mallocFailed flag in the connection pointer.
|
||||||
*/
|
*/
|
||||||
void *sqlite3DbMallocRaw(sqlite3 *db, unsigned n){
|
void *sqlite3DbMallocRaw(sqlite3 *db, int n){
|
||||||
void *p = 0;
|
void *p = 0;
|
||||||
if( !db || db->mallocFailed==0 ){
|
if( !db || db->mallocFailed==0 ){
|
||||||
p = sqlite3_malloc(n);
|
p = sqlite3Malloc(n);
|
||||||
if( !p && db ){
|
if( !p && db ){
|
||||||
db->mallocFailed = 1;
|
db->mallocFailed = 1;
|
||||||
}
|
}
|
||||||
|
296
src/mem1.c
296
src/mem1.c
@@ -9,10 +9,15 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** 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.c,v 1.18 2008/06/13 18:24:27 drh Exp $
|
** This file contains low-level memory allocation drivers for when
|
||||||
|
** SQLite will use the standard C-library malloc/realloc/free interface
|
||||||
|
** to obtain the memory it needs.
|
||||||
|
**
|
||||||
|
** This file contains implementations of the low-level memory allocation
|
||||||
|
** routines specified in the sqlite3_mem_methods object.
|
||||||
|
**
|
||||||
|
** $Id: mem1.c,v 1.19 2008/06/14 16:56:22 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -24,219 +29,112 @@
|
|||||||
#ifdef SQLITE_SYSTEM_MALLOC
|
#ifdef SQLITE_SYSTEM_MALLOC
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** All of the static variables used by this module are collected
|
** Like malloc(), but remember the size of the allocation
|
||||||
** into a single structure named "mem". This is to keep the
|
** so that we can find it later using sqlite3MemSize().
|
||||||
** static variables organized and to reduce namespace pollution
|
**
|
||||||
** when this module is combined with other in the amalgamation.
|
** For this low-level routine, we are guaranteed that nByte>0 because
|
||||||
|
** cases of nByte<=0 will be intercepted and dealt with by higher level
|
||||||
|
** routines.
|
||||||
*/
|
*/
|
||||||
static struct {
|
static void *sqlite3MemMalloc(int nByte){
|
||||||
/*
|
|
||||||
** 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.
|
|
||||||
*/
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
void *sqlite3_malloc(int nBytes){
|
|
||||||
sqlite3_int64 *p = 0;
|
|
||||||
if( nBytes>0 ){
|
|
||||||
enterMem();
|
|
||||||
if( mem.alarmCallback!=0 && mem.nowUsed+nBytes>=mem.alarmThreshold ){
|
|
||||||
sqlite3MemsysAlarm(nBytes);
|
|
||||||
}
|
|
||||||
if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){
|
|
||||||
p = 0;
|
|
||||||
}else{
|
|
||||||
p = malloc(nBytes+8);
|
|
||||||
if( p==0 ){
|
|
||||||
sqlite3MemsysAlarm(nBytes);
|
|
||||||
p = 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.
|
|
||||||
*/
|
|
||||||
void sqlite3_free(void *pPrior){
|
|
||||||
sqlite3_int64 *p;
|
sqlite3_int64 *p;
|
||||||
int nByte;
|
assert( nByte>0 );
|
||||||
if( pPrior==0 ){
|
nByte = (nByte+7)&~7;
|
||||||
return;
|
p = malloc( nByte+8 );
|
||||||
}
|
p[0] = nByte;
|
||||||
assert( mem.mutex!=0 );
|
return (void*)&p[1];
|
||||||
p = pPrior;
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Like free() but works for allocations obtained from sqlite3MemMalloc()
|
||||||
|
** or sqlite3MemRealloc().
|
||||||
|
**
|
||||||
|
** For this low-level routine, we already know that pPrior!=0 since
|
||||||
|
** cases where pPrior==0 will have been intecepted and dealt with
|
||||||
|
** by higher-level routines.
|
||||||
|
*/
|
||||||
|
static void sqlite3MemFree(void *pPrior){
|
||||||
|
assert( pPrior!=0 );
|
||||||
|
sqlite3_int64 *p = (sqlite3_int64*)pPrior;
|
||||||
p--;
|
p--;
|
||||||
nByte = (int)*p;
|
|
||||||
sqlite3_mutex_enter(mem.mutex);
|
|
||||||
mem.nowUsed -= nByte;
|
|
||||||
free(p);
|
free(p);
|
||||||
sqlite3_mutex_leave(mem.mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return the number of bytes allocated at p.
|
** Like realloc(). Resize an allocation previously obtained from
|
||||||
|
** sqlite3MemMalloc().
|
||||||
|
**
|
||||||
|
** For this low-level interface, we know that pPrior!=0. Cases where
|
||||||
|
** pPrior==0 while have been intercepted by higher-level routine and
|
||||||
|
** redirected to xMalloc. Similarly, we know that nByte>0 becauses
|
||||||
|
** cases where nByte<=0 will have been intercepted by higher-level
|
||||||
|
** routines and redirected to xFree.
|
||||||
*/
|
*/
|
||||||
int sqlite3MallocSize(void *p){
|
static void *sqlite3MemRealloc(void *pPrior, int nByte){
|
||||||
sqlite3_int64 *pInt;
|
sqlite3_int64 *p = (sqlite3_int64*)pPrior;
|
||||||
if( !p ) return 0;
|
assert( pPrior!=0 && nByte>0 );
|
||||||
pInt = p;
|
nByte = (nByte+7)&~7;
|
||||||
return pInt[-1];
|
p = (sqlite3_int64*)pPrior;
|
||||||
|
p--;
|
||||||
|
p = realloc(p, nByte+8 );
|
||||||
|
if( p ){
|
||||||
|
p[0] = nByte;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
return (void*)p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Initialize the memmory allocation subsystem.
|
** Report the allocated size of a prior return from xMalloc()
|
||||||
|
** or xRealloc().
|
||||||
*/
|
*/
|
||||||
int sqlite3MallocInit(void){
|
static int sqlite3MemSize(void *pPrior){
|
||||||
|
sqlite3_int64 *p;
|
||||||
|
if( pPrior==0 ) return 0;
|
||||||
|
p = (sqlite3_int64*)pPrior;
|
||||||
|
p--;
|
||||||
|
return p[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Round up a request size to the next valid allocation size.
|
||||||
|
*/
|
||||||
|
static int sqlite3MemRoundup(int n){
|
||||||
|
return (n+7) & ~7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Initialize this module.
|
||||||
|
*/
|
||||||
|
static int sqlite3MemInit(void *NotUsed){
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Change the size of an existing memory allocation
|
** Deinitialize this module.
|
||||||
*/
|
*/
|
||||||
void *sqlite3_realloc(void *pPrior, int nBytes){
|
static void sqlite3MemShutdown(void *NotUsed){
|
||||||
int nOld;
|
return;
|
||||||
sqlite3_int64 *p;
|
}
|
||||||
if( pPrior==0 ){
|
|
||||||
return sqlite3_malloc(nBytes);
|
/*
|
||||||
}
|
** This routine is the only routine in this file with external linkage.
|
||||||
if( nBytes<=0 ){
|
**
|
||||||
sqlite3_free(pPrior);
|
** Populate the low-level memory allocation function pointers in
|
||||||
return 0;
|
** sqlite3Config.m with pointers to the routines in this file.
|
||||||
}
|
*/
|
||||||
p = pPrior;
|
void sqlite3MemSetDefault(void){
|
||||||
p--;
|
static const sqlite3_mem_methods defaultMethods = {
|
||||||
nOld = (int)p[0];
|
sqlite3MemMalloc,
|
||||||
assert( mem.mutex!=0 );
|
sqlite3MemFree,
|
||||||
sqlite3_mutex_enter(mem.mutex);
|
sqlite3MemRealloc,
|
||||||
if( mem.nowUsed+nBytes-nOld>=mem.alarmThreshold ){
|
sqlite3MemSize,
|
||||||
sqlite3MemsysAlarm(nBytes-nOld);
|
sqlite3MemRoundup,
|
||||||
}
|
sqlite3MemInit,
|
||||||
if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){
|
sqlite3MemShutdown,
|
||||||
p = 0;
|
0
|
||||||
}else{
|
};
|
||||||
p = realloc(p, nBytes+8);
|
sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
|
||||||
if( p==0 ){
|
|
||||||
sqlite3MemsysAlarm(nBytes);
|
|
||||||
p = pPrior;
|
|
||||||
p--;
|
|
||||||
p = 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_SYSTEM_MALLOC */
|
#endif /* SQLITE_SYSTEM_MALLOC */
|
||||||
|
278
src/mem2.c
278
src/mem2.c
@@ -9,10 +9,17 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** 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: mem2.c,v 1.27 2008/06/13 18:24:27 drh Exp $
|
** This file contains low-level memory allocation drivers for when
|
||||||
|
** SQLite will use the standard C-library malloc/realloc/free interface
|
||||||
|
** to obtain the memory it needs while adding lots of additional debugging
|
||||||
|
** information to each allocation in order to help detect and fix memory
|
||||||
|
** leaks and memory usage errors.
|
||||||
|
**
|
||||||
|
** This file contains implementations of the low-level memory allocation
|
||||||
|
** routines specified in the sqlite3_mem_methods object.
|
||||||
|
**
|
||||||
|
** $Id: mem2.c,v 1.28 2008/06/14 16:56:22 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -74,29 +81,12 @@ struct MemBlockHdr {
|
|||||||
** when this module is combined with other in the amalgamation.
|
** when this module is combined with other in the amalgamation.
|
||||||
*/
|
*/
|
||||||
static struct {
|
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.
|
** Mutex to control access to the memory allocation subsystem.
|
||||||
*/
|
*/
|
||||||
sqlite3_mutex *mutex;
|
sqlite3_mutex *mutex;
|
||||||
|
|
||||||
/*
|
|
||||||
** Current allocation and high-water mark.
|
|
||||||
*/
|
|
||||||
sqlite3_int64 nowUsed;
|
|
||||||
sqlite3_int64 mxUsed;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Head and tail of a linked list of all outstanding allocations
|
** Head and tail of a linked list of all outstanding allocations
|
||||||
*/
|
*/
|
||||||
@@ -131,78 +121,6 @@ static struct {
|
|||||||
|
|
||||||
} mem;
|
} 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.
|
|
||||||
*/
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Given an allocation, find the MemBlockHdr for that allocation.
|
** Given an allocation, find the MemBlockHdr for that allocation.
|
||||||
**
|
**
|
||||||
@@ -231,7 +149,7 @@ static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){
|
|||||||
/*
|
/*
|
||||||
** Return the number of bytes currently allocated at address p.
|
** Return the number of bytes currently allocated at address p.
|
||||||
*/
|
*/
|
||||||
int sqlite3MallocSize(void *p){
|
static int sqlite3MemSize(void *p){
|
||||||
struct MemBlockHdr *pHdr;
|
struct MemBlockHdr *pHdr;
|
||||||
if( !p ){
|
if( !p ){
|
||||||
return 0;
|
return 0;
|
||||||
@@ -241,106 +159,100 @@ int sqlite3MallocSize(void *p){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Initialize the memmory allocation subsystem.
|
** Initialize the memory allocation subsystem.
|
||||||
*/
|
*/
|
||||||
int sqlite3MallocInit(void){
|
static int sqlite3MemInit(void *NotUsed){
|
||||||
|
mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Deinitialize the memory allocation subsystem.
|
||||||
|
*/
|
||||||
|
static void sqlite3MemShutdown(void *NotUsed){
|
||||||
|
sqlite3_mutex_free(mem.mutex);
|
||||||
|
mem.mutex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Round up a request size to the next valid allocation size.
|
||||||
|
*/
|
||||||
|
static int sqlite3MemRoundup(int n){
|
||||||
|
return (n+7) & ~7;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Allocate nByte bytes of memory.
|
** Allocate nByte bytes of memory.
|
||||||
*/
|
*/
|
||||||
void *sqlite3_malloc(int nByte){
|
static void *sqlite3MemMalloc(int nByte){
|
||||||
struct MemBlockHdr *pHdr;
|
struct MemBlockHdr *pHdr;
|
||||||
void **pBt;
|
void **pBt;
|
||||||
char *z;
|
char *z;
|
||||||
int *pInt;
|
int *pInt;
|
||||||
void *p = 0;
|
void *p = 0;
|
||||||
int totalSize;
|
int totalSize;
|
||||||
|
int nReserve;
|
||||||
if( nByte>0 ){
|
sqlite3_mutex_enter(mem.mutex);
|
||||||
int nReserve;
|
assert( mem.disallow==0 );
|
||||||
enterMem();
|
nReserve = (nByte+7)&~7;
|
||||||
assert( mem.disallow==0 );
|
if( nReserve/8>NCSIZE-1 ){
|
||||||
if( mem.alarmCallback!=0 && mem.nowUsed+nByte>=mem.alarmThreshold ){
|
mem.sizeCnt[NCSIZE-1]++;
|
||||||
sqlite3MemsysAlarm(nByte);
|
}else{
|
||||||
}
|
mem.sizeCnt[nReserve/8]++;
|
||||||
nReserve = (nByte+7)&~7;
|
|
||||||
if( nReserve/8>NCSIZE-1 ){
|
|
||||||
mem.sizeCnt[NCSIZE-1]++;
|
|
||||||
}else{
|
|
||||||
mem.sizeCnt[nReserve/8]++;
|
|
||||||
}
|
|
||||||
totalSize = nReserve + sizeof(*pHdr) + sizeof(int) +
|
|
||||||
mem.nBacktrace*sizeof(void*) + mem.nTitle;
|
|
||||||
if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){
|
|
||||||
p = 0;
|
|
||||||
}else{
|
|
||||||
p = malloc(totalSize);
|
|
||||||
if( p==0 ){
|
|
||||||
sqlite3MemsysAlarm(nByte);
|
|
||||||
p = malloc(totalSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( p ){
|
|
||||||
z = p;
|
|
||||||
pBt = (void**)&z[mem.nTitle];
|
|
||||||
pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace];
|
|
||||||
pHdr->pNext = 0;
|
|
||||||
pHdr->pPrev = mem.pLast;
|
|
||||||
if( mem.pLast ){
|
|
||||||
mem.pLast->pNext = pHdr;
|
|
||||||
}else{
|
|
||||||
mem.pFirst = pHdr;
|
|
||||||
}
|
|
||||||
mem.pLast = pHdr;
|
|
||||||
pHdr->iForeGuard = FOREGUARD;
|
|
||||||
pHdr->nBacktraceSlots = mem.nBacktrace;
|
|
||||||
pHdr->nTitle = mem.nTitle;
|
|
||||||
if( mem.nBacktrace ){
|
|
||||||
void *aAddr[40];
|
|
||||||
pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1;
|
|
||||||
memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*));
|
|
||||||
if( mem.xBacktrace ){
|
|
||||||
mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
pHdr->nBacktrace = 0;
|
|
||||||
}
|
|
||||||
if( mem.nTitle ){
|
|
||||||
memcpy(z, mem.zTitle, mem.nTitle);
|
|
||||||
}
|
|
||||||
pHdr->iSize = nByte;
|
|
||||||
pInt = (int*)&pHdr[1];
|
|
||||||
pInt[nReserve/sizeof(int)] = REARGUARD;
|
|
||||||
memset(pInt, 0x65, nReserve);
|
|
||||||
mem.nowUsed += nByte;
|
|
||||||
if( mem.nowUsed>mem.mxUsed ){
|
|
||||||
mem.mxUsed = mem.nowUsed;
|
|
||||||
}
|
|
||||||
p = (void*)pInt;
|
|
||||||
}
|
|
||||||
sqlite3_mutex_leave(mem.mutex);
|
|
||||||
}
|
}
|
||||||
|
totalSize = nReserve + sizeof(*pHdr) + sizeof(int) +
|
||||||
|
mem.nBacktrace*sizeof(void*) + mem.nTitle;
|
||||||
|
p = malloc(totalSize);
|
||||||
|
if( p ){
|
||||||
|
z = p;
|
||||||
|
pBt = (void**)&z[mem.nTitle];
|
||||||
|
pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace];
|
||||||
|
pHdr->pNext = 0;
|
||||||
|
pHdr->pPrev = mem.pLast;
|
||||||
|
if( mem.pLast ){
|
||||||
|
mem.pLast->pNext = pHdr;
|
||||||
|
}else{
|
||||||
|
mem.pFirst = pHdr;
|
||||||
|
}
|
||||||
|
mem.pLast = pHdr;
|
||||||
|
pHdr->iForeGuard = FOREGUARD;
|
||||||
|
pHdr->nBacktraceSlots = mem.nBacktrace;
|
||||||
|
pHdr->nTitle = mem.nTitle;
|
||||||
|
if( mem.nBacktrace ){
|
||||||
|
void *aAddr[40];
|
||||||
|
pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1;
|
||||||
|
memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*));
|
||||||
|
if( mem.xBacktrace ){
|
||||||
|
mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
pHdr->nBacktrace = 0;
|
||||||
|
}
|
||||||
|
if( mem.nTitle ){
|
||||||
|
memcpy(z, mem.zTitle, mem.nTitle);
|
||||||
|
}
|
||||||
|
pHdr->iSize = nByte;
|
||||||
|
pInt = (int*)&pHdr[1];
|
||||||
|
pInt[nReserve/sizeof(int)] = REARGUARD;
|
||||||
|
memset(pInt, 0x65, nReserve);
|
||||||
|
p = (void*)pInt;
|
||||||
|
}
|
||||||
|
sqlite3_mutex_leave(mem.mutex);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Free memory.
|
** Free memory.
|
||||||
*/
|
*/
|
||||||
void sqlite3_free(void *pPrior){
|
static void sqlite3MemFree(void *pPrior){
|
||||||
struct MemBlockHdr *pHdr;
|
struct MemBlockHdr *pHdr;
|
||||||
void **pBt;
|
void **pBt;
|
||||||
char *z;
|
char *z;
|
||||||
if( pPrior==0 ){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
assert( mem.mutex!=0 );
|
assert( mem.mutex!=0 );
|
||||||
pHdr = sqlite3MemsysGetHeader(pPrior);
|
pHdr = sqlite3MemsysGetHeader(pPrior);
|
||||||
pBt = (void**)pHdr;
|
pBt = (void**)pHdr;
|
||||||
pBt -= pHdr->nBacktraceSlots;
|
pBt -= pHdr->nBacktraceSlots;
|
||||||
sqlite3_mutex_enter(mem.mutex);
|
sqlite3_mutex_enter(mem.mutex);
|
||||||
mem.nowUsed -= pHdr->iSize;
|
|
||||||
if( pHdr->pPrev ){
|
if( pHdr->pPrev ){
|
||||||
assert( pHdr->pPrev->pNext==pHdr );
|
assert( pHdr->pPrev->pNext==pHdr );
|
||||||
pHdr->pPrev->pNext = pHdr->pNext;
|
pHdr->pPrev->pNext = pHdr->pNext;
|
||||||
@@ -372,29 +284,41 @@ void sqlite3_free(void *pPrior){
|
|||||||
** much more likely to break and we are much more liking to find
|
** much more likely to break and we are much more liking to find
|
||||||
** the error.
|
** the error.
|
||||||
*/
|
*/
|
||||||
void *sqlite3_realloc(void *pPrior, int nByte){
|
static void *sqlite3MemRealloc(void *pPrior, int nByte){
|
||||||
struct MemBlockHdr *pOldHdr;
|
struct MemBlockHdr *pOldHdr;
|
||||||
void *pNew;
|
void *pNew;
|
||||||
if( pPrior==0 ){
|
|
||||||
return sqlite3_malloc(nByte);
|
|
||||||
}
|
|
||||||
if( nByte<=0 ){
|
|
||||||
sqlite3_free(pPrior);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
assert( mem.disallow==0 );
|
assert( mem.disallow==0 );
|
||||||
pOldHdr = sqlite3MemsysGetHeader(pPrior);
|
pOldHdr = sqlite3MemsysGetHeader(pPrior);
|
||||||
pNew = sqlite3_malloc(nByte);
|
pNew = sqlite3MemMalloc(nByte);
|
||||||
if( pNew ){
|
if( pNew ){
|
||||||
memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize);
|
memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize);
|
||||||
if( nByte>pOldHdr->iSize ){
|
if( nByte>pOldHdr->iSize ){
|
||||||
memset(&((char*)pNew)[pOldHdr->iSize], 0x2b, nByte - pOldHdr->iSize);
|
memset(&((char*)pNew)[pOldHdr->iSize], 0x2b, nByte - pOldHdr->iSize);
|
||||||
}
|
}
|
||||||
sqlite3_free(pPrior);
|
sqlite3MemFree(pPrior);
|
||||||
}
|
}
|
||||||
return pNew;
|
return pNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Populate the low-level memory allocation function pointers in
|
||||||
|
** sqlite3Config.m with pointers to the routines in this file.
|
||||||
|
*/
|
||||||
|
void sqlite3MemSetDefault(void){
|
||||||
|
static const sqlite3_mem_methods defaultMethods = {
|
||||||
|
sqlite3MemMalloc,
|
||||||
|
sqlite3MemFree,
|
||||||
|
sqlite3MemRealloc,
|
||||||
|
sqlite3MemSize,
|
||||||
|
sqlite3MemRoundup,
|
||||||
|
sqlite3MemInit,
|
||||||
|
sqlite3MemShutdown,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Set the number of backtrace levels kept for each allocation.
|
** Set the number of backtrace levels kept for each allocation.
|
||||||
** A value of zero turns of backtracing. The number is always rounded
|
** A value of zero turns of backtracing. The number is always rounded
|
||||||
@@ -416,7 +340,7 @@ void sqlite3MemdebugBacktraceCallback(void (*xBacktrace)(int, int, void **)){
|
|||||||
*/
|
*/
|
||||||
void sqlite3MemdebugSettitle(const char *zTitle){
|
void sqlite3MemdebugSettitle(const char *zTitle){
|
||||||
int n = strlen(zTitle) + 1;
|
int n = strlen(zTitle) + 1;
|
||||||
enterMem();
|
sqlite3_mutex_enter(mem.mutex);
|
||||||
if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1;
|
if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1;
|
||||||
memcpy(mem.zTitle, zTitle, n);
|
memcpy(mem.zTitle, zTitle, n);
|
||||||
mem.zTitle[n] = 0;
|
mem.zTitle[n] = 0;
|
||||||
@@ -474,7 +398,7 @@ void sqlite3MemdebugDump(const char *zFilename){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return the number of times sqlite3_malloc() has been called.
|
** Return the number of times sqlite3MemMalloc() has been called.
|
||||||
*/
|
*/
|
||||||
int sqlite3MemdebugMallocCount(){
|
int sqlite3MemdebugMallocCount(){
|
||||||
int i;
|
int i;
|
||||||
|
27
src/mutex.c
27
src/mutex.c
@@ -19,7 +19,7 @@
|
|||||||
** implementation is suitable for testing.
|
** implementation is suitable for testing.
|
||||||
** debugging purposes
|
** debugging purposes
|
||||||
**
|
**
|
||||||
** $Id: mutex.c,v 1.18 2008/06/13 18:24:27 drh Exp $
|
** $Id: mutex.c,v 1.19 2008/06/14 16:56:23 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ sqlite3_mutex *sqlite3_mutex_alloc(int id){
|
|||||||
** This routine deallocates a previously allocated mutex.
|
** This routine deallocates a previously allocated mutex.
|
||||||
*/
|
*/
|
||||||
void sqlite3_mutex_free(sqlite3_mutex *p){
|
void sqlite3_mutex_free(sqlite3_mutex *p){
|
||||||
assert( p );
|
if( p==0 ) return;
|
||||||
assert( p->cnt==0 );
|
assert( p->cnt==0 );
|
||||||
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
|
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
|
||||||
sqlite3_free(p);
|
sqlite3_free(p);
|
||||||
@@ -95,14 +95,16 @@ void sqlite3_mutex_free(sqlite3_mutex *p){
|
|||||||
** more than once, the behavior is undefined.
|
** more than once, the behavior is undefined.
|
||||||
*/
|
*/
|
||||||
void sqlite3_mutex_enter(sqlite3_mutex *p){
|
void sqlite3_mutex_enter(sqlite3_mutex *p){
|
||||||
assert( p );
|
if( p ){
|
||||||
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
||||||
p->cnt++;
|
p->cnt++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int sqlite3_mutex_try(sqlite3_mutex *p){
|
int sqlite3_mutex_try(sqlite3_mutex *p){
|
||||||
assert( p );
|
if( p ){
|
||||||
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
||||||
p->cnt++;
|
p->cnt++;
|
||||||
|
}
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,10 +115,11 @@ int sqlite3_mutex_try(sqlite3_mutex *p){
|
|||||||
** is not currently allocated. SQLite will never do either.
|
** is not currently allocated. SQLite will never do either.
|
||||||
*/
|
*/
|
||||||
void sqlite3_mutex_leave(sqlite3_mutex *p){
|
void sqlite3_mutex_leave(sqlite3_mutex *p){
|
||||||
assert( p );
|
if( p ){
|
||||||
assert( sqlite3_mutex_held(p) );
|
assert( sqlite3_mutex_held(p) );
|
||||||
p->cnt--;
|
p->cnt--;
|
||||||
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
** the version number) and changes its name to "sqlite3.h" as
|
** the version number) and changes its name to "sqlite3.h" as
|
||||||
** part of the build process.
|
** part of the build process.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqlite.h.in,v 1.326 2008/06/13 18:24:27 drh Exp $
|
** @(#) $Id: sqlite.h.in,v 1.327 2008/06/14 16:56:23 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITE3_H_
|
#ifndef _SQLITE3_H_
|
||||||
#define _SQLITE3_H_
|
#define _SQLITE3_H_
|
||||||
@@ -942,6 +942,60 @@ int sqlite3_os_end(void);
|
|||||||
*/
|
*/
|
||||||
int sqlite3_config(int, ...);
|
int sqlite3_config(int, ...);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** CAPI3REF: Memory Allocation Routines {F10155}
|
||||||
|
**
|
||||||
|
** An instance of this object defines the interface between SQLite
|
||||||
|
** and low-level memory allocation routines.
|
||||||
|
**
|
||||||
|
** This object is used in only one place in the SQLite interface.
|
||||||
|
** A pointer to an instance of this object is the argument to
|
||||||
|
** [sqlite3_config] when the configuration option is
|
||||||
|
** [SQLITE_CONFIG_MALLOC]. By creating an instance of this object
|
||||||
|
** and passing it to [sqlite3_config] during configuration, an
|
||||||
|
** application can specify an alternative memory allocation subsystem
|
||||||
|
** for SQLite to use for all of its dynamic memory needs.
|
||||||
|
**
|
||||||
|
** Note that SQLite comes with a built-in memory allocator that is
|
||||||
|
** perfectly adequate for the overwhelming majority of applications
|
||||||
|
** and that this object is only useful to a tiny minority of applications
|
||||||
|
** with specialized memory allocation requirements. This object is
|
||||||
|
** also used during testing of SQLite in order to specify an alternative
|
||||||
|
** memory allocator that simulates memory out-of-memory conditions in
|
||||||
|
** order to verify that SQLite recovers gracefully from such
|
||||||
|
** conditions.
|
||||||
|
**
|
||||||
|
** The xMalloc, xFree, and xRealloc methods should work like the
|
||||||
|
** malloc(), free(), and realloc() functions from the standard library.
|
||||||
|
**
|
||||||
|
** xSize should return the allocated size of a memory allocation
|
||||||
|
** previously obtained from xMalloc or xRealloc. The allocated size
|
||||||
|
** is always at least as big as the requested size but may be larger.
|
||||||
|
**
|
||||||
|
** The xRoundup method returns what would be the allocated size of
|
||||||
|
** a memory allocation given a particular requested size. Most memory
|
||||||
|
** allocators round up memory allocations at least to the next multiple
|
||||||
|
** of 8. Some round up to a larger multiple or to a power of 2.
|
||||||
|
**
|
||||||
|
** The xInit method initializes the memory allocator. (For example,
|
||||||
|
** it might allocate any require mutexes or initialize internal data
|
||||||
|
** structures. The xShutdown method is invoked (indirectly) by
|
||||||
|
** [sqlite3_shutdown()] and should deallocate any resources acquired
|
||||||
|
** by xInit. The pAppData pointer is used as the only parameter to
|
||||||
|
** xInit and xShutdown.
|
||||||
|
*/
|
||||||
|
typedef struct sqlite3_mem_methods sqlite3_mem_methods;
|
||||||
|
struct sqlite3_mem_methods {
|
||||||
|
void *(*xMalloc)(int); /* Memory allocation function */
|
||||||
|
void (*xFree)(void*); /* Free a prior allocation */
|
||||||
|
void *(*xRealloc)(void*,int); /* Resize an allocation */
|
||||||
|
int (*xSize)(void*); /* Return the size of an allocation */
|
||||||
|
int (*xRoundup)(int); /* Round up request size to allocation size */
|
||||||
|
int (*xInit)(void*); /* Initialize the memory allocator */
|
||||||
|
void (*xShutdown)(void*); /* Deinitialize the memory allocator */
|
||||||
|
void *pAppData; /* Argument to xInit() and xShutdown() */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Configuration Options {F10160}
|
** CAPI3REF: Configuration Options {F10160}
|
||||||
**
|
**
|
||||||
@@ -973,16 +1027,12 @@ int sqlite3_config(int, ...);
|
|||||||
** same [prepared statement] in different threads at the same time.</dd>
|
** same [prepared statement] in different threads at the same time.</dd>
|
||||||
**
|
**
|
||||||
** <dt>SQLITE_CONFIG_MALLOC</dt>
|
** <dt>SQLITE_CONFIG_MALLOC</dt>
|
||||||
** <dd>This option takes five arguments. The first three
|
** <dd>This option takes a single argument which is a pointer to an
|
||||||
** arguments are pointers to functions that emulate malloc(), free(),
|
** instance of the [sqlite3_mem_methods] structure. The argument specifics
|
||||||
** and realloc(), respectively. The fourth argument must be a pointer to
|
** alternative low-level memory allocation routines to be used in place
|
||||||
** a function that returns the size of a prior allocation when handed a pointer
|
** the memory allocation routines built into SQLite.</dd>
|
||||||
** to the allocation. The fifth argument is a pointer to a function that
|
|
||||||
** returns the rounded-up size of a memory allocation given the requested
|
|
||||||
** allocation size. This option is used to replace the default memory
|
|
||||||
** allocator with an application-defined memory allocator.</dd>
|
|
||||||
**
|
**
|
||||||
** <dt>SQLITE_CONFIG_MEMSTATS</dt>
|
** <dt>SQLITE_CONFIG_MEMSTATUS</dt>
|
||||||
** <dd>This option takes single boolean argument which enables or disables
|
** <dd>This option takes single boolean argument which enables or disables
|
||||||
** the collection of memory allocation statistics. When disabled, the
|
** the collection of memory allocation statistics. When disabled, the
|
||||||
** following SQLite interfaces become non-operational:
|
** following SQLite interfaces become non-operational:
|
||||||
@@ -998,8 +1048,8 @@ int sqlite3_config(int, ...);
|
|||||||
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
|
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
|
||||||
#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
|
#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
|
||||||
#define SQLITE_CONFIG_SERIALIZED 3 /* nil */
|
#define SQLITE_CONFIG_SERIALIZED 3 /* nil */
|
||||||
#define SQLITE_CONFIG_MALLOC 4 /* malloc,free,realloc,memsize,roundup */
|
#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */
|
||||||
#define SQLITE_CONFIG_MEMSTATS 5 /* boolean */
|
#define SQLITE_CONFIG_MEMSTATUS 5 /* boolean */
|
||||||
|
|
||||||
/* These options are to be added later. Currently unused and undocumented. */
|
/* These options are to be added later. Currently unused and undocumented. */
|
||||||
#define SQLITE_CONFIG_HEAP 6 /* void*, int64, min, max, tmp */
|
#define SQLITE_CONFIG_HEAP 6 /* void*, int64, min, max, tmp */
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.708 2008/06/13 18:24:27 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.709 2008/06/14 16:56:23 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@@ -1735,18 +1735,14 @@ typedef struct {
|
|||||||
** Structure containing global configuration data for the SQLite library.
|
** Structure containing global configuration data for the SQLite library.
|
||||||
*/
|
*/
|
||||||
struct Sqlite3Config {
|
struct Sqlite3Config {
|
||||||
void *(*xMalloc)(int); /* Low-level malloc() */
|
int bMemstat; /* True to enable memory status */
|
||||||
void *(*xRealloc)(void*,int); /* Low-level realloc() */
|
int bCoreMutex; /* True to enable core mutexing */
|
||||||
void (*xFree)(void*); /* Low-level free() */
|
int bFullMutex; /* True to enable full mutexing */
|
||||||
int (*xMemsize)(void*); /* Return size of an allocation */
|
sqlite3_mem_methods m; /* Low-level memory allocation interface */
|
||||||
int (*xRoundup)(int); /* Size of allocation given request */
|
|
||||||
void *pHeap; /* Heap storage space */
|
void *pHeap; /* Heap storage space */
|
||||||
sqlite3_int64 nHeap; /* Size of pHeap[] */
|
sqlite3_int64 nHeap; /* Size of pHeap[] */
|
||||||
int mnReq, mxReq; /* Min and max memory request sizes */
|
int mnReq, mxReq; /* Min and max memory request sizes */
|
||||||
int nTemp; /* Part of pHeap for temporary allos */
|
int nTemp; /* Part of pHeap for temporary allos */
|
||||||
int bMemstat; /* True to enable memory status */
|
|
||||||
int bCoreMutex; /* True to enable core mutexing */
|
|
||||||
int bFullMutex; /* True to enable full mutexing */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1782,16 +1778,20 @@ int sqlite3StrNICmp(const char *, const char *, int);
|
|||||||
int sqlite3IsNumber(const char*, int*, u8);
|
int sqlite3IsNumber(const char*, int*, u8);
|
||||||
|
|
||||||
int sqlite3MallocInit(void);
|
int sqlite3MallocInit(void);
|
||||||
void *sqlite3MallocZero(unsigned);
|
void sqlite3MallocEnd(void);
|
||||||
void *sqlite3DbMallocZero(sqlite3*, unsigned);
|
void *sqlite3Malloc(int);
|
||||||
void *sqlite3DbMallocRaw(sqlite3*, unsigned);
|
void *sqlite3MallocZero(int);
|
||||||
|
void *sqlite3DbMallocZero(sqlite3*, int);
|
||||||
|
void *sqlite3DbMallocRaw(sqlite3*, int);
|
||||||
char *sqlite3StrDup(const char*);
|
char *sqlite3StrDup(const char*);
|
||||||
char *sqlite3StrNDup(const char*, int);
|
char *sqlite3StrNDup(const char*, int);
|
||||||
char *sqlite3DbStrDup(sqlite3*,const char*);
|
char *sqlite3DbStrDup(sqlite3*,const char*);
|
||||||
char *sqlite3DbStrNDup(sqlite3*,const char*, int);
|
char *sqlite3DbStrNDup(sqlite3*,const char*, int);
|
||||||
|
void *sqlite3Realloc(void*, int);
|
||||||
void *sqlite3DbReallocOrFree(sqlite3 *, void *, int);
|
void *sqlite3DbReallocOrFree(sqlite3 *, void *, int);
|
||||||
void *sqlite3DbRealloc(sqlite3 *, void *, int);
|
void *sqlite3DbRealloc(sqlite3 *, void *, int);
|
||||||
int sqlite3MallocSize(void *);
|
int sqlite3MallocSize(void *);
|
||||||
|
void sqlite3MemSetDefault(void);
|
||||||
|
|
||||||
int sqlite3IsNaN(double);
|
int sqlite3IsNaN(double);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user