diff options
author | drh <drh@noemail.net> | 2019-04-25 18:15:38 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2019-04-25 18:15:38 +0000 |
commit | 10c0e7115b2ed28a2af6f3b59a9c2862b1b25f9d (patch) | |
tree | c70d09692d22d9acb6a875c095ba36bb35455c43 /src/malloc.c | |
parent | dbdd93b7e1b6f4e129df36309868a4c1fb002207 (diff) | |
download | sqlite-10c0e7115b2ed28a2af6f3b59a9c2862b1b25f9d.tar.gz sqlite-10c0e7115b2ed28a2af6f3b59a9c2862b1b25f9d.zip |
Add the sqlite3_hard_heap_limit64() interface and the corresponding
"PRAGMA hard_heap_limit=N" command.
FossilOrigin-Name: b0ccef61a7f92d20228becbf4f997bf0f4e46dad2deaf0896dc63b976ad1dd11
Diffstat (limited to 'src/malloc.c')
-rw-r--r-- | src/malloc.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/src/malloc.c b/src/malloc.c index 559e7259c..2027a4c8c 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -38,6 +38,7 @@ int sqlite3_release_memory(int n){ static SQLITE_WSD struct Mem0Global { sqlite3_mutex *mutex; /* Mutex to serialize access */ sqlite3_int64 alarmThreshold; /* The soft heap limit */ + sqlite3_int64 hardLimit; /* The hard upper bound on memory */ /* ** True if heap is nearly "full" where "full" is defined by the @@ -74,8 +75,15 @@ int sqlite3_memory_alarm( #endif /* -** Set the soft heap-size limit for the library. Passing a zero or -** negative value indicates no limit. +** Set the soft heap-size limit for the library. An argument of +** zero disables the limit. A negative argument is a no-op used to +** obtain the return value. +** +** The return value is the value of the heap limit just before this +** interface was called. +** +** If the hard heap limit is enabled, then the soft heap limit cannot +** be disabled nor raised above the hard heap limit. */ sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){ sqlite3_int64 priorLimit; @@ -91,6 +99,9 @@ sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){ sqlite3_mutex_leave(mem0.mutex); return priorLimit; } + if( mem0.hardLimit>0 && (n>mem0.hardLimit || n==0) ){ + n = mem0.hardLimit; + } mem0.alarmThreshold = n; nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); mem0.nearlyFull = (n>0 && n<=nUsed); @@ -105,6 +116,37 @@ void sqlite3_soft_heap_limit(int n){ } /* +** Set the hard heap-size limit for the library. An argument of zero +** disables the hard heap limit. A negative argument is a no-op used +** to obtain the return value without affecting the hard heap limit. +** +** The return value is the value of the hard heap limit just prior to +** calling this interface. +** +** Setting the hard heap limit will also activate the soft heap limit +** and constrain the soft heap limit to be no more than the hard heap +** limit. +*/ +sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 n){ + sqlite3_int64 priorLimit; +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return -1; +#endif + sqlite3_mutex_enter(mem0.mutex); + priorLimit = mem0.hardLimit; + if( n>=0 ){ + mem0.hardLimit = n; + if( n<mem0.alarmThreshold || mem0.alarmThreshold==0 ){ + mem0.alarmThreshold = n; + } + } + sqlite3_mutex_leave(mem0.mutex); + return priorLimit; +} + + +/* ** Initialize the memory allocation subsystem. */ int sqlite3MallocInit(void){ @@ -203,6 +245,13 @@ static void mallocWithAlarm(int n, void **pp){ if( nUsed >= mem0.alarmThreshold - nFull ){ mem0.nearlyFull = 1; sqlite3MallocAlarm(nFull); + if( mem0.hardLimit ){ + nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + if( nUsed >= mem0.hardLimit - nFull ){ + *pp = 0; + return; + } + } }else{ mem0.nearlyFull = 0; } |