aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordanielk1977 <danielk1977@noemail.net>2008-08-21 12:19:44 +0000
committerdanielk1977 <danielk1977@noemail.net>2008-08-21 12:19:44 +0000
commit67e3da7ad43b63ff9efbb69565aae4ec87cf0941 (patch)
treee2b68d949e64099ab52787b7ba331ef9730062e3 /src
parent0d3c5d3239a658aaff40b86f5c5c7c2e64b21dc3 (diff)
downloadsqlite-67e3da7ad43b63ff9efbb69565aae4ec87cf0941.tar.gz
sqlite-67e3da7ad43b63ff9efbb69565aae4ec87cf0941.zip
Fix the functionality associated with sqlite3_release_memory() and sqlite3_soft_heap_limit(). It is automatically disabled if the SQLITE_CONFIG_PAGECACHE option is used. (CVS 5576)
FossilOrigin-Name: d025866b09352b32a6d35b97144eaad2fafb7165
Diffstat (limited to 'src')
-rw-r--r--src/malloc.c9
-rw-r--r--src/pager.c49
-rw-r--r--src/pager.h6
-rw-r--r--src/pcache.c137
-rw-r--r--src/pcache.h4
-rw-r--r--src/vdbeapi.c4
6 files changed, 125 insertions, 84 deletions
diff --git a/src/malloc.c b/src/malloc.c
index 663e44f1f..a1727e603 100644
--- a/src/malloc.c
+++ b/src/malloc.c
@@ -12,7 +12,7 @@
**
** Memory allocation functions used throughout sqlite.
**
-** $Id: malloc.c,v 1.35 2008/08/20 14:49:24 danielk1977 Exp $
+** $Id: malloc.c,v 1.36 2008/08/21 12:19:44 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
@@ -62,8 +62,11 @@ void sqlite3_soft_heap_limit(int n){
*/
int sqlite3_release_memory(int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
- int nRet = sqlite3VdbeReleaseMemory(n);
- nRet += sqlite3PagerReleaseMemory(n-nRet);
+ int nRet = 0;
+#if 0
+ nRet += sqlite3VdbeReleaseMemory(n);
+#endif
+ nRet += sqlite3PcacheReleaseMemory(n-nRet);
return nRet;
#else
return SQLITE_OK;
diff --git a/src/pager.c b/src/pager.c
index 1c56a7a8f..b9a71c0a0 100644
--- a/src/pager.c
+++ b/src/pager.c
@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.472 2008/08/21 04:35:19 danielk1977 Exp $
+** @(#) $Id: pager.c,v 1.473 2008/08/21 12:19:44 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
@@ -2453,22 +2453,26 @@ static int pagerStress(void *p){
PgHdr *pPg = sqlite3PcacheDirtyPage(pPager->pPCache);
int rc = SQLITE_OK;
- if( pPg && pPager->errCode==SQLITE_OK ){
+ if( pPg ){
assert( pPg->flags&PGHDR_DIRTY );
- if( pPg->flags&PGHDR_NEED_SYNC ){
- rc = syncJournal(pPager);
- if( rc==SQLITE_OK && pPager->fullSync
- && !(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
- ){
- pPager->nRec = 0;
- rc = writeJournalHdr(pPager);
+ if( pPager->errCode==SQLITE_OK ){
+ if( pPg->flags&PGHDR_NEED_SYNC ){
+ rc = syncJournal(pPager);
+ if( rc==SQLITE_OK && pPager->fullSync &&
+ !(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
+ ){
+ pPager->nRec = 0;
+ rc = writeJournalHdr(pPager);
+ }
}
- }
- if( rc==SQLITE_OK ){
- rc = pager_write_pagelist(pPg);
- }
- if( rc!=SQLITE_OK ){
- pager_error(pPager, rc);
+ if( rc==SQLITE_OK ){
+ rc = pager_write_pagelist(pPg);
+ }
+ if( rc!=SQLITE_OK ){
+ pager_error(pPager, rc);
+ }
+ }else{
+ sqlite3PcacheMakeClean(pPg);
}
}
return rc;
@@ -2523,21 +2527,6 @@ static int hasHotJournal(Pager *pPager, int *pExists){
return rc;
}
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
-/*
-** This function is called to free superfluous dynamically allocated memory
-** held by the pager system. Memory in use by any SQLite pager allocated
-** by the current thread may be sqlite3_free()ed.
-**
-** nReq is the number of bytes of memory required. Once this much has
-** been released, the function returns. The return value is the total number
-** of bytes of memory released.
-*/
-int sqlite3PagerReleaseMemory(int nReq){
- return 0;
-}
-#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
-
/*
** Read the content of page pPg out of the database file.
*/
diff --git a/src/pager.h b/src/pager.h
index d6a200b41..356466c9c 100644
--- a/src/pager.h
+++ b/src/pager.h
@@ -13,7 +13,7 @@
** subsystem. The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
-** @(#) $Id: pager.h,v 1.78 2008/08/20 14:49:25 danielk1977 Exp $
+** @(#) $Id: pager.h,v 1.79 2008/08/21 12:19:44 danielk1977 Exp $
*/
#ifndef _PAGER_H_
@@ -115,10 +115,6 @@ void *sqlite3PagerTempSpace(Pager*);
int sqlite3PagerSync(Pager *pPager);
void sqlite3PagerAlwaysRollback(Pager *pPager);
-#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
- int sqlite3PagerReleaseMemory(int);
-#endif
-
#ifdef SQLITE_HAS_CODEC
void sqlite3PagerSetCodec(Pager*,void*(*)(void*,void*,Pgno,int),void*);
#endif
diff --git a/src/pcache.c b/src/pcache.c
index ffaa5e8f4..89fc85354 100644
--- a/src/pcache.c
+++ b/src/pcache.c
@@ -11,7 +11,7 @@
*************************************************************************
** This file implements that page cache.
**
-** @(#) $Id: pcache.c,v 1.3 2008/08/21 04:41:02 danielk1977 Exp $
+** @(#) $Id: pcache.c,v 1.4 2008/08/21 12:19:44 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -331,7 +331,10 @@ void *pcacheMalloc(int sz){
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
return (void*)p;
}else{
- void *p = sqlite3Malloc(sz);
+ void *p;
+ pcacheExitGlobal();
+ p = sqlite3Malloc(sz);
+ pcacheEnterGlobal();
if( p ){
sz = sqlite3MallocSize(p);
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
@@ -407,55 +410,47 @@ static void pcachePageFree(PgHdr *p){
}
/*
-** Obtain space for a page. Try to recycle an old page if the limit on the
-** number of pages has been reached. If the limit has not been reached or
-** there are no pages eligible for recycling, allocate a new page.
-**
-** Return a pointer to the new page, or NULL if an OOM condition occurs.
+** Return the number of bytes that will be returned to the heap when
+** the argument is passed to pcachePageFree().
*/
-static PgHdr *pcacheRecycleOrAlloc(PCache *pCache){
- PgHdr *p = 0;
+static int pcachePageSize(PgHdr *p){
+ assert( sqlite3_mutex_held(pcache.mutex_lru) );
+ assert( !pcache.pStart );
+ assert( p->apSave[0]==0 );
+ assert( p->apSave[1]==0 );
+ assert( p && p->pCache );
+ return sqlite3MallocSize(p);
+}
- int szPage = pCache->szPage;
- int szExtra = pCache->szExtra;
- int bPurg = pCache->bPurgeable;
+static PgHdr *pcacheRecycle(PCache *pCache){
+ PCache *pCsr;
+ PgHdr *p = 0;
assert( pcache.isInit );
- assert( sqlite3_mutex_notheld(pcache.mutex_lru) );
+ assert( sqlite3_mutex_held(pcache.mutex_lru) );
- pcacheEnterGlobal();
+ if( !pcache.pLruTail && SQLITE_OK==sqlite3_mutex_try(pcache.mutex_mem2) ){
- if( (pcache.mxPage && pcache.nPage>=pcache.mxPage)
- || (!pcache.mxPage && bPurg && pcache.nPurgeable>=pcache.mxPagePurgeable)
- ){
- PCache *pCsr;
-
- /* If the above test succeeds, then a page will be obtained by recycling
- ** an existing page.
+ /* Invoke xStress() callbacks until the LRU list contains at least one
+ ** page that can be reused or until the xStress() callback of all
+ ** caches has been invoked.
*/
- if( !pcache.pLruTail && SQLITE_OK==sqlite3_mutex_try(pcache.mutex_mem2) ){
-
- /* Invoke xStress() callbacks until the LRU list contains at least one
- ** page that can be reused or until the xStress() callback of all
- ** caches has been invoked.
- */
- for(pCsr=pcache.pAll; pCsr&&!pcache.pLruTail; pCsr=pCsr->pNextAll){
- assert( pCsr->iInUseMM==0 );
- pCsr->iInUseMM = 1;
- if( pCsr->xStress && (pCsr->iInUseDB==0 || pCache==pCsr) ){
- pcacheExitGlobal();
- pCsr->xStress(pCsr->pStress);
- pcacheEnterGlobal();
- }
- pCsr->iInUseMM = 0;
+ for(pCsr=pcache.pAll; pCsr&&!pcache.pLruTail; pCsr=pCsr->pNextAll){
+ assert( pCsr->iInUseMM==0 );
+ pCsr->iInUseMM = 1;
+ if( pCsr->xStress && (pCsr->iInUseDB==0 || pCache==pCsr) ){
+ pcacheExitGlobal();
+ pCsr->xStress(pCsr->pStress);
+ pcacheEnterGlobal();
}
-
- sqlite3_mutex_leave(pcache.mutex_mem2);
+ pCsr->iInUseMM = 0;
}
- p = pcache.pLruTail;
+ sqlite3_mutex_leave(pcache.mutex_mem2);
}
+ p = pcache.pLruTail;
+
if( p ){
pcacheRemoveFromLruList(p);
pcacheRemoveFromHash(p);
@@ -468,11 +463,41 @@ static PgHdr *pcacheRecycleOrAlloc(PCache *pCache){
assert(p->pPager);
sqlite3PagerAlwaysRollback(p->pPager);
}
+ }
- if( p->pCache->szPage!=szPage || p->pCache->szExtra!=szExtra ){
- pcachePageFree(p);
- p = 0;
- }
+ return p;
+}
+
+/*
+** Obtain space for a page. Try to recycle an old page if the limit on the
+** number of pages has been reached. If the limit has not been reached or
+** there are no pages eligible for recycling, allocate a new page.
+**
+** Return a pointer to the new page, or NULL if an OOM condition occurs.
+*/
+static PgHdr *pcacheRecycleOrAlloc(PCache *pCache){
+ PgHdr *p = 0;
+
+ int szPage = pCache->szPage;
+ int szExtra = pCache->szExtra;
+ int bPurg = pCache->bPurgeable;
+
+ assert( pcache.isInit );
+ assert( sqlite3_mutex_notheld(pcache.mutex_lru) );
+
+ pcacheEnterGlobal();
+
+ if( (pcache.mxPage && pcache.nPage>=pcache.mxPage)
+ || (!pcache.mxPage && bPurg && pcache.nPurgeable>=pcache.mxPagePurgeable)
+ ){
+ /* If the above test succeeds, then try to obtain a buffer by recycling
+ ** an existing page. */
+ p = pcacheRecycle(pCache);
+ }
+
+ if( p && (p->pCache->szPage!=szPage || p->pCache->szExtra!=szExtra) ){
+ pcachePageFree(p);
+ p = 0;
}
if( !p ){
@@ -1141,3 +1166,29 @@ void sqlite3PcacheUnlock(PCache *pCache){
pCache->iInUseDB--;
assert( pCache->iInUseDB>=0 );
}
+
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+/*
+** This function is called to free superfluous dynamically allocated memory
+** held by the pager system. Memory in use by any SQLite pager allocated
+** by the current thread may be sqlite3_free()ed.
+**
+** nReq is the number of bytes of memory required. Once this much has
+** been released, the function returns. The return value is the total number
+** of bytes of memory released.
+*/
+int sqlite3PcacheReleaseMemory(int nReq){
+ int nFree = 0;
+ if( pcache.pStart==0 ){
+ PgHdr *p;
+ pcacheEnterGlobal();
+ while( (nReq<0 || nFree<nReq) && (p=pcacheRecycle(0)) ){
+ nFree += pcachePageSize(p);
+ pcachePageFree(p);
+ }
+ pcacheExitGlobal();
+ }
+ return nFree;
+}
+#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
+
diff --git a/src/pcache.h b/src/pcache.h
index 15772f8bd..f45d64457 100644
--- a/src/pcache.h
+++ b/src/pcache.h
@@ -12,7 +12,7 @@
** This header file defines the interface that the sqlite page cache
** subsystem.
**
-** @(#) $Id: pcache.h,v 1.1 2008/08/20 14:49:25 danielk1977 Exp $
+** @(#) $Id: pcache.h,v 1.2 2008/08/21 12:19:44 danielk1977 Exp $
*/
#ifndef _PCACHE_H_
@@ -171,5 +171,7 @@ void sqlite3PcacheSetCachesize(PCache *, int);
void sqlite3PcacheLock(PCache *);
void sqlite3PcacheUnlock(PCache *);
+int sqlite3PcacheReleaseMemory(int);
+
#endif /* _PCACHE_H_ */
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index 8006355d5..cc09f072f 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -13,12 +13,12 @@
** This file contains code use to implement APIs that are part of the
** VDBE.
**
-** $Id: vdbeapi.c,v 1.139 2008/08/11 18:44:58 drh Exp $
+** $Id: vdbeapi.c,v 1.140 2008/08/21 12:19:44 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+#if 0 && defined(SQLITE_ENABLE_MEMORY_MANAGEMENT)
/*
** The following structure contains pointers to the end points of a
** doubly-linked list of all compiled SQL statements that may be holding