1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Add a runtime interface to enable memory-management features. (CVS 2894)

FossilOrigin-Name: 44f8e3139aa3ad3fcce9028565dd9ad23bbe62a2
This commit is contained in:
danielk1977
2006-01-09 09:59:49 +00:00
parent e501b89ada
commit 52622828ce
9 changed files with 156 additions and 68 deletions

View File

@@ -1,5 +1,5 @@
C Rename\sDbSchema\sto\s"Schema"\sand\sSqliteTsd\sto\s"ThreadData".\s(CVS\s2893)
D 2006-01-09T06:29:48
C Add\sa\sruntime\sinterface\sto\senable\smemory-management\sfeatures.\s(CVS\s2894)
D 2006-01-09T09:59:49
F Makefile.in c79fbdaa264c6afcd435f2fb492551de5a8cf80d
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -34,7 +34,7 @@ F src/alter.c d0dd079b9ef0d551ff4a4ce09ee270c07b307bbb
F src/analyze.c ed87abad3f6f60e1bd5308ed6ff6e0fa396db52b
F src/attach.c 833e38b4fa6966de05fcf875c94cd521478a2811
F src/auth.c cdec356a5cd8b217c346f816c5912221537fe87f
F src/btree.c fc3f7f936b4f58c05ce95d710c1c15bb86cd522a
F src/btree.c 5e5dff4a667d93d49925d38de2d451a5bd1eabfd
F src/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184
F src/build.c e40a4caaba4afab3fc7f0866ca8766e8146dd62c
F src/callback.c 79cfbac59139b525e3a195ee27b8be1ca06fbd38
@@ -59,7 +59,7 @@ F src/os_unix.c c5d1a3fe88ad93b5f6a29f1b5b889f2a756aaec0
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
F src/os_win.c 9cedcb13d6bcd4ab5f50907a99112f45cd335893
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c f838695a6c0c8d0051ce7491036fd675052aa6f6
F src/pager.c 6fbcc25f1f3fbe62cbbda3af3dbb9c3d758f8050
F src/pager.h e0acb095b3ad0bca48f2ab00c87346665643f64f
F src/parse.y 83df51fea35f68f7e07384d75dce83d1ed30434c
F src/pragma.c 7358baf8e2be14a0f3d71e7afae41e430d76b054
@@ -68,11 +68,11 @@ F src/printf.c f47a2f4b5387cd2ebb12e9117a1a5d6bd9a2b812
F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
F src/select.c d97a43973d82a2e1e24be43ca5543c08b93e9e8d
F src/shell.c 66b073375efbdee19045e7e0cd38b85f9aff71da
F src/sqlite.h.in ba3a29daa6a16e054191ccb384a981964e882a1d
F src/sqliteInt.h 9fed92df9ab1cccbe649c28e6d24685a1f3373a4
F src/sqlite.h.in 537bac9e9ef703695268aaad5c56b6bf64f815be
F src/sqliteInt.h f9e4b620da09737e678271d45135088027d80307
F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316
F src/tclsqlite.c 42151e6c78502277be77b88c00535d53ce89b917
F src/test1.c 25e687fcc3c962958c5aa5114a74592cc5b7e6ba
F src/test1.c a526810f7d1c73b7b9a85621dd655d4357e0ae6d
F src/test2.c ca74a1d8aeb7d9606e8f6b762c5daf85c1a3f92b
F src/test3.c 9742aa146eb750cab81c1d5605286c3a0eb88054
F src/test4.c a8fd681e139e1c61f22a77d07fc3a99cb28fff3f
@@ -82,7 +82,7 @@ F src/tokenize.c 196486012c871cdcad6cc84a820cc988603f1b9d
F src/trigger.c c515afa5fe964e9854c54dc66dde179a90d0cfe3
F src/update.c 9a3761250c2ac9e6871f4e9c37560b224ba0067e
F src/utf.c b7bffac4260177ae7f83c01d025fe0f5ed70ce71
F src/util.c 9af2eab4203627982e433102be55b58dd38f8a38
F src/util.c 0153015d99468e994a2c9bc6746262654ed5914a
F src/vacuum.c f5a068096b22fad438bf1f1cf69ccb7f9e8cc7fb
F src/vdbe.c ce31105fc91e1ea346e2383cd536149cc66c34bd
F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
@@ -186,7 +186,7 @@ F test/malloc.test 6245418d1b6635a2095d9ed0f5e84e029990da06
F test/malloc2.test e6e321db96d6c94cb18bf82ad7215070c41e624e
F test/malloc3.test 9797d39eca7087a1022bcc0eb0b22215475c9698
F test/malloc4.test 2e29d155eb4b4808019ef47eeedfcbe9e09e0f05
F test/malloc5.test 4ebf827a8173e1429480a6b276d37e89c6ab96f0
F test/malloc5.test 1bac8c0dd98c387460920c1190f0996c5c62ea66
F test/manydb.test d81debbf5871242e3b5df1d3bb5e14c50431b6f8
F test/memdb.test 1860e060be810bf0775bc57408a5b7c4954bcaea
F test/memleak.test df2b2b96e77f8ba159a332299535b1e5f18e49ac
@@ -335,7 +335,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
P cc963f8cfc6c704c645c627bffb8df21dfebffc6
R 7000da8baf46b4c1ff76e715121c7c17
P 82b81f69c78cb3f54634d9aea4f6a838474dc5e5
R bcf9f7930a1367ea3da4936a55af71d7
U danielk1977
Z c505bc6b6a245c795a8be1eda400ccd9
Z b19a6ec12413214a65f445404992c64a

View File

@@ -1 +1 @@
82b81f69c78cb3f54634d9aea4f6a838474dc5e5
44f8e3139aa3ad3fcce9028565dd9ad23bbe62a2

View File

@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.287 2006/01/09 06:29:48 danielk1977 Exp $
** $Id: btree.c,v 1.288 2006/01/09 09:59:49 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
@@ -6504,11 +6504,19 @@ int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){
** Enable the shared pager and schema features.
*/
int sqlite3_enable_shared_cache(int enable){
ThreadData *pTsd = sqlite3ThreadData();
if( pTsd->pPager ){
ThreadData *pTd = sqlite3ThreadData();
/* It is only legal to call sqlite3_enable_shared_cache() when there
** are no currently open b-trees that were opened by the calling thread.
** This condition is only easy to detect if the shared-cache were
** previously enabled (and is being disabled).
*/
if( pTd->pBtree && !enable ){
assert( pTd->useSharedData );
return SQLITE_MISUSE;
}
pTsd->useSharedData = enable;
pTd->useSharedData = enable;
return SQLITE_OK;
}
#endif

View File

@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.232 2006/01/09 06:29:49 danielk1977 Exp $
** @(#) $Id: pager.c,v 1.233 2006/01/09 09:59:49 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
@@ -1623,7 +1623,9 @@ int sqlite3pager_open(
int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
char zTemp[SQLITE_TEMPNAME_SIZE];
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
ThreadData *pTsd = sqlite3ThreadData();
#endif
/* If malloc() has already failed return SQLITE_NOMEM. Before even
** testing for this, set *ppPager to NULL so the caller knows the pager
@@ -1723,8 +1725,12 @@ int sqlite3pager_open(
pPager->pBusyHandler = 0;
memset(pPager->aHash, 0, sizeof(pPager->aHash));
*ppPager = pPager;
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
if( pTsd->useMemoryManagement ){
pPager->pNext = pTsd->pPager;
pTsd->pPager = pPager;
}
#endif
return SQLITE_OK;
}
@@ -2088,8 +2094,9 @@ int sqlite3pager_close(Pager *pPager){
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
/* Remove the pager from the linked list of pagers starting at
** ThreadData.pPager.
** ThreadData.pPager if memory-management is enabled.
*/
if( pTsd->useMemoryManagement ){
if( pPager==pTsd->pPager ){
pTsd->pPager = pPager->pNext;
}else{
@@ -2097,6 +2104,7 @@ int sqlite3pager_close(Pager *pPager){
for(pTmp = pTsd->pPager; pTmp->pNext!=pPager; pTmp=pTmp->pNext);
pTmp->pNext = pPager->pNext;
}
}
#endif
sqliteFree(pPager);

View File

@@ -12,7 +12,7 @@
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.152 2005/12/30 16:28:02 danielk1977 Exp $
** @(#) $Id: sqlite.h.in,v 1.153 2006/01/09 09:59:49 danielk1977 Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
@@ -1276,21 +1276,6 @@ int sqlite3_get_autocommit(sqlite3*);
*/
sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
/*
** Place a "soft" limit on the amount of heap memory that may be allocated by
** SQLite within the current thread. If an internal allocation is requested
** that would exceed the specified limit, sqlite3_release_memory() is invoked
** one or more times to free up some space before the allocation is made.
**
** The limit is called "soft", because if sqlite3_release_memory() cannot free
** sufficient memory to prevent the limit from being exceeded, the memory is
** allocated anyway and the current operation proceeds.
**
** This function is only available if the library was compiled without the
** SQLITE_OMIT_MEMORY_MANAGEMENT option set.
*/
void sqlite3_soft_heap_limit(sqlite_int64);
/*
** Register a callback function with the database connection identified by the
** first argument to be invoked whenever a row is updated, inserted or deleted.
@@ -1336,8 +1321,6 @@ void *sqlite3_update_hook(
*/
void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
int sqlite3_release_memory(int);
/*
** This function is only available if the library is compiled without
** the SQLITE_OMIT_SHARED_CACHE macro defined. It is used to enable or
@@ -1346,6 +1329,40 @@ int sqlite3_release_memory(int);
*/
int sqlite3_enable_shared_cache(int);
/*
** This function is only available if the library is compiled without
** the SQLITE_OMIT_MEMORY_MANAGEMENT macro defined. It is used to enable or
** disable (if the argument is true or false, respectively) the
** "memory management" features (accessed via the sqlite3_soft_heap_limit()
** and sqlite3_release_memory() APIs).
*/
int sqlite3_enable_memory_management(int);
/*
** Attempt to free N bytes of heap memory by deallocating non-essential
** memory allocations held by the database library (example: memory
** used to cache database pages to improve performance).
**
** This function is a no-op unless memory-management has been enabled.
*/
int sqlite3_release_memory(int);
/*
** Place a "soft" limit on the amount of heap memory that may be allocated by
** SQLite within the current thread. If an internal allocation is requested
** that would exceed the specified limit, sqlite3_release_memory() is invoked
** one or more times to free up some space before the allocation is made.
**
** The limit is called "soft", because if sqlite3_release_memory() cannot free
** sufficient memory to prevent the limit from being exceeded, the memory is
** allocated anyway and the current operation proceeds.
**
** This function is only available if the library was compiled without the
** SQLITE_OMIT_MEMORY_MANAGEMENT option set. It is a no-op unless
** memory-management has been enabled.
*/
void sqlite3_soft_heap_limit(sqlite_int64);
/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.

View File

@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.454 2006/01/09 06:29:49 danielk1977 Exp $
** @(#) $Id: sqliteInt.h,v 1.455 2006/01/09 09:59:49 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -294,6 +294,7 @@ struct ThreadData {
u8 disableReleaseMemory; /* True to make sqlite3_release_memory() a no-op */
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
u8 useMemoryManagement; /* True if memory-management is enabled */
i64 nSoftHeapLimit; /* Suggested max mem allocation. No limit if <0 */
i64 nAlloc; /* Number of bytes currently allocated */
Pager *pPager; /* Linked list of all pagers in this thread */

View File

@@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.184 2006/01/09 06:29:49 danielk1977 Exp $
** $Id: test1.c,v 1.185 2006/01/09 09:59:49 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
@@ -903,21 +903,16 @@ static int sqlite_malloc_outstanding(
){
extern int sqlite3OutstandingMallocs(Tcl_Interp *interp);
if( objc!=1 && objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "?-bytes?");
return TCL_ERROR;
}
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
if( objc==2 ){
ThreadData *pTd = sqlite3ThreadData();
const char *zArg = Tcl_GetString(objv[1]);
if( 0==strcmp(zArg, "-bytes") ){
Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3ThreadData()->nAlloc));
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
Tcl_SetObjResult(interp, Tcl_NewIntObj(pTd->nAlloc));
}else if( 0==strcmp(zArg, "-maxbytes") ){
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sqlite3ThreadData()->nMaxAlloc));
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pTd->nMaxAlloc));
}else if( 0==strcmp(zArg, "-clearmaxbytes") ){
sqlite3ThreadData()->nMaxAlloc = sqlite3ThreadData()->nAlloc;
#endif
pTd->nMaxAlloc = pTd->nAlloc;
}else{
Tcl_AppendResult(interp, "bad option \"", zArg,
"\": must be -bytes, -maxbytes or -clearmaxbytes", 0
@@ -927,6 +922,12 @@ static int sqlite_malloc_outstanding(
return TCL_OK;
}
#endif
if( objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "?-bytes?");
return TCL_ERROR;
}
return sqlite3OutstandingMallocs(interp);
}
@@ -934,20 +935,33 @@ static int sqlite_malloc_outstanding(
/*
** Usage: sqlite3_enable_shared_cache BOOLEAN
** Usage: sqlite3_enable_memory_management BOOLEAN
**
*/
#ifndef SQLITE_OMIT_SHARED_CACHE
static int test_enable_shared_cache(
ClientData clientData,
#if !defined(SQLITE_OMIT_SHARED_CACHE)||!defined(SQLITE_OMIT_MEMORY_MANAGEMENT)
static int test_enable(
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
int rc;
int enable;
int ret = 0;
int (*xFunc)(int) = (int(*)(int))clientData;
ThreadData *pTsd = sqlite3ThreadData();
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(pTsd->useSharedData));
#ifndef SQLITE_OMIT_SHARED_CACHE
if( xFunc==sqlite3_enable_shared_cache ){
ret = pTsd->useSharedData;
}else
#endif
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
{
assert( xFunc==sqlite3_enable_memory_management );
ret = pTsd->useMemoryManagement;
}
#endif
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");
return TCL_ERROR;
@@ -955,11 +969,12 @@ static int test_enable_shared_cache(
if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ){
return TCL_ERROR;
}
rc = sqlite3_enable_shared_cache(enable);
rc = xFunc(enable);
if( rc!=SQLITE_OK ){
Tcl_SetResult(interp, (char *)sqlite3ErrStr(rc), TCL_STATIC);
return TCL_ERROR;
}
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(ret));
return TCL_OK;
}
#endif
@@ -3414,7 +3429,11 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_test_errstr", test_errstr, 0 },
{ "tcl_variable_type", tcl_variable_type, 0 },
#ifndef SQLITE_OMIT_SHARED_CACHE
{ "sqlite3_enable_shared_cache", test_enable_shared_cache, 0},
{ "sqlite3_enable_shared_cache", test_enable, sqlite3_enable_shared_cache},
#endif
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
{ "sqlite3_enable_memory_management", test_enable,
sqlite3_enable_memory_management},
#endif
};
static int bitmask_size = sizeof(Bitmask)*8;

View File

@@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.163 2006/01/09 06:29:49 danielk1977 Exp $
** $Id: util.c,v 1.164 2006/01/09 09:59:49 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -529,7 +529,7 @@ static void handleSoftLimit(int n){
}
}
#else
#define handleSoftLimit()
#define handleSoftLimit(x)
#endif
/*
@@ -1307,7 +1307,9 @@ void *sqlite3TextToPtr(const char *z){
ThreadData *sqlite3ThreadData(){
ThreadData *pTsd = sqlite3OsThreadSpecificData(sizeof(ThreadData));
if( pTsd && !pTsd->isInit ){
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
pTsd->nSoftHeapLimit = -1;
#endif
#ifndef NDEBUG
pTsd->mallocAllowed = 1;
#endif
@@ -1324,6 +1326,25 @@ void sqlite3MallocClearFailed(){
sqlite3ThreadData()->mallocFailed = 0;
}
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
/*
** Enable the shared pager and schema features.
*/
int sqlite3_enable_memory_management(int enable){
ThreadData *pTsd = sqlite3ThreadData();
/* It is only legal to call sqlite3_enable_memory_management() when there
** are no currently open connections that were opened by the calling
** thread. This condition is only easy to detect if the feature were
** previously enabled (and is being disabled).
*/
if( pTsd->pPager && !enable ){
return SQLITE_MISUSE;
}
pTsd->useMemoryManagement = enable;
return SQLITE_OK;
}
#endif
#ifndef NDEBUG
/*

View File

@@ -12,15 +12,17 @@
# This file contains test cases focused on the two memory-management APIs,
# sqlite3_soft_heap_limit() and sqlite3_release_memory().
#
# $Id: malloc5.test,v 1.4 2006/01/05 15:50:07 drh Exp $
# $Id: malloc5.test,v 1.5 2006/01/09 09:59:49 danielk1977 Exp $
#---------------------------------------------------------------------------
# NOTES ON EXPECTED BEHAVIOUR
#
#---------------------------------------------------------------------------
set testdir [file dirname $argv0]
source $testdir/tester.tcl
db close
# Only run these tests if memory debugging is turned on.
if {[info command sqlite_malloc_stat]==""} {
@@ -29,6 +31,15 @@ if {[info command sqlite_malloc_stat]==""} {
return
}
# Skip these tests if OMIT_MEMORY_MANAGEMENT was defined at compile time.
ifcapable !memorymanage {
finish_test
return
}
sqlite3_enable_memory_management 1
sqlite3 db test.db
do_test malloc5-1.1 {
# Simplest possible test. Call sqlite3_release_memory when there is exactly
# one unused page in a single pager cache. This test case set's the
@@ -205,5 +216,8 @@ do_test malloc5-4.3 {
# Restore the soft heap limit.
sqlite3_soft_heap_limit $::soft_limit
finish_test
catch {db close}
sqlite3_enable_memory_management 0