aboutsummaryrefslogtreecommitdiff
path: root/src/malloc.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2015-09-02 14:56:56 +0000
committerdrh <drh@noemail.net>2015-09-02 14:56:56 +0000
commit4ef299a32ca49f0cd55fff2a42c166a9e70c8b66 (patch)
tree988a071635e45c25b61cf031b06e44cc4284e65e /src/malloc.c
parent02bf8b45b7a12ec3cb78046c0b15c91a4e0e6d64 (diff)
downloadsqlite-4ef299a32ca49f0cd55fff2a42c166a9e70c8b66.tar.gz
sqlite-4ef299a32ca49f0cd55fff2a42c166a9e70c8b66.zip
The sqlite3_memory_alarm() interface has been deprecated and undocumented
for almost 8 years (since version 3.5.3). Change it into a no-op. FossilOrigin-Name: 5d3f5df4da9f40d5897b5c23b2ea9333fc18ac2c
Diffstat (limited to 'src/malloc.c')
-rw-r--r--src/malloc.c135
1 files changed, 53 insertions, 82 deletions
diff --git a/src/malloc.c b/src/malloc.c
index f402728e7..23d7598ae 100644
--- a/src/malloc.c
+++ b/src/malloc.c
@@ -45,16 +45,7 @@ typedef struct ScratchFreeslot {
*/
static SQLITE_WSD struct Mem0Global {
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.
- */
- sqlite3_int64 alarmThreshold;
- void (*alarmCallback)(void*, sqlite3_int64,int);
- void *alarmArg;
+ sqlite3_int64 alarmThreshold; /* The soft heap limit */
/*
** Pointers to the end of sqlite3GlobalConfig.pScratch memory
@@ -71,7 +62,7 @@ static SQLITE_WSD struct Mem0Global {
** sqlite3_soft_heap_limit() setting.
*/
int nearlyFull;
-} mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 };
+} mem0 = { 0, 0, 0, 0, 0, 0 };
#define mem0 GLOBAL(struct Mem0Global, mem0)
@@ -83,49 +74,59 @@ sqlite3_mutex *sqlite3MallocMutex(void){
}
/*
-** This routine runs when the memory allocator sees that the
-** total memory allocation is about to exceed the soft heap
-** limit.
+** Return the amount of memory currently in use.
*/
-static void softHeapLimitEnforcer(
- void *NotUsed,
- sqlite3_int64 NotUsed2,
- int allocSize
-){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- sqlite3_release_memory(allocSize);
+static sqlite3_int64 memInUse(void){
+ assert( sqlite3_mutex_held(mem0.mutex) );
+ return sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
}
/*
-** Change the alarm callback
+** Called when the soft heap limit is exceeded for an allocation
+** of nBytes.
*/
-static int sqlite3MemoryAlarm(
- void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
- void *pArg,
- sqlite3_int64 iThreshold
-){
- sqlite3_int64 nUsed;
- sqlite3_mutex_enter(mem0.mutex);
- mem0.alarmCallback = xCallback;
- mem0.alarmArg = pArg;
- mem0.alarmThreshold = iThreshold;
- nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
- mem0.nearlyFull = (iThreshold>0 && iThreshold<=nUsed);
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+static void sqlite3HeapLimitExceeded(int nByte){
+ sqlite3_int64 excess = memInUse() + nByte - mem0.alarmThreshold;
sqlite3_mutex_leave(mem0.mutex);
- return SQLITE_OK;
+ sqlite3_release_memory((int)(excess & 0x7fffffff));
+ sqlite3_mutex_enter(mem0.mutex);
+}
+#else
+# define sqlite3HeapLimitExceeded(X) /* no-op */
+#endif
+
+/*
+** Check to see if increasing the total memory usage by nNew bytes
+** will exceed the soft heap limit.
+**
+** If the soft heap limit is exceeded, set the mem0.nearlyFull flag
+** and invoke sqlite3HeapLimitExceeded() to try to free up some
+** memory.
+*/
+static void sqlite3CheckSoftHeapLimit(int nNew){
+ assert( sqlite3_mutex_held(mem0.mutex) );
+ if( mem0.alarmThreshold>0 ){
+ if( mem0.alarmThreshold-nNew >= memInUse() ){
+ mem0.nearlyFull = 1;
+ sqlite3HeapLimitExceeded(nNew);
+ }else{
+ mem0.nearlyFull = 0;
+ }
+ }
}
#ifndef SQLITE_OMIT_DEPRECATED
/*
-** Deprecated external interface. Internal/core SQLite code
-** should call sqlite3MemoryAlarm.
+** Deprecated external interface. First deprecated 2007-11-05. Changed
+** into a no-op on 2015-09-02.
*/
int sqlite3_memory_alarm(
void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
void *pArg,
sqlite3_int64 iThreshold
){
- return sqlite3MemoryAlarm(xCallback, pArg, iThreshold);
+ return SQLITE_OK;
}
#endif
@@ -135,22 +136,20 @@ int sqlite3_memory_alarm(
*/
sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
sqlite3_int64 priorLimit;
- sqlite3_int64 excess;
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
if( rc ) return -1;
#endif
sqlite3_mutex_enter(mem0.mutex);
priorLimit = mem0.alarmThreshold;
- sqlite3_mutex_leave(mem0.mutex);
- if( n<0 ) return priorLimit;
if( n>0 ){
- sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, n);
- }else{
- sqlite3MemoryAlarm(0, 0, 0);
+ mem0.alarmThreshold = n;
+ sqlite3CheckSoftHeapLimit(0);
+ }else if( n==0 ){
+ mem0.alarmThreshold = 0;
+ mem0.nearlyFull = 0;
}
- excess = sqlite3_memory_used() - n;
- if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
+ sqlite3_mutex_leave(mem0.mutex);
return priorLimit;
}
void sqlite3_soft_heap_limit(int n){
@@ -242,25 +241,6 @@ sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
}
/*
-** Trigger the alarm
-*/
-static void sqlite3MallocAlarm(int nByte){
- void (*xCallback)(void*,sqlite3_int64,int);
- sqlite3_int64 nowUsed;
- void *pArg;
- if( mem0.alarmCallback==0 ) return;
- xCallback = mem0.alarmCallback;
- nowUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
- pArg = mem0.alarmArg;
- mem0.alarmCallback = 0;
- sqlite3_mutex_leave(mem0.mutex);
- xCallback(pArg, nowUsed, nByte);
- sqlite3_mutex_enter(mem0.mutex);
- mem0.alarmCallback = xCallback;
- mem0.alarmArg = pArg;
-}
-
-/*
** Do a memory allocation with statistics and alarms. Assume the
** lock is already held.
*/
@@ -270,19 +250,11 @@ static int mallocWithAlarm(int n, void **pp){
assert( sqlite3_mutex_held(mem0.mutex) );
nFull = sqlite3GlobalConfig.m.xRoundup(n);
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
- if( mem0.alarmCallback!=0 ){
- sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
- if( nUsed >= mem0.alarmThreshold - nFull ){
- mem0.nearlyFull = 1;
- sqlite3MallocAlarm(nFull);
- }else{
- mem0.nearlyFull = 0;
- }
- }
+ sqlite3CheckSoftHeapLimit(nFull);
p = sqlite3GlobalConfig.m.xMalloc(nFull);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
- if( p==0 && mem0.alarmCallback ){
- sqlite3MallocAlarm(nFull);
+ if( p==0 && mem0.alarmThreshold ){
+ sqlite3HeapLimitExceeded(nFull);
p = sqlite3GlobalConfig.m.xMalloc(nFull);
}
#endif
@@ -565,15 +537,14 @@ void *sqlite3Realloc(void *pOld, u64 nBytes){
sqlite3_mutex_enter(mem0.mutex);
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
nDiff = nNew - nOld;
- if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
- mem0.alarmThreshold-nDiff ){
- sqlite3MallocAlarm(nDiff);
- }
+ sqlite3CheckSoftHeapLimit(nDiff);
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
- if( pNew==0 && mem0.alarmCallback ){
- sqlite3MallocAlarm((int)nBytes);
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+ if( pNew==0 && mem0.alarmThreshold ){
+ sqlite3HeapLimitExceeded((int)nBytes);
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
}
+#endif
if( pNew ){
nNew = sqlite3MallocSize(pNew);
sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld);