diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/malloc.c | 9 | ||||
-rw-r--r-- | src/pager.c | 49 | ||||
-rw-r--r-- | src/pager.h | 6 | ||||
-rw-r--r-- | src/pcache.c | 137 | ||||
-rw-r--r-- | src/pcache.h | 4 | ||||
-rw-r--r-- | src/vdbeapi.c | 4 |
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 |