Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | 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) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
d025866b09352b32a6d35b97144eaad2 |
User & Date: | danielk1977 2008-08-21 12:19:44.000 |
Context
2008-08-21
| ||
12:32 | Patch to mkfunction to try and detect miscompiles. Add an unimportant assert back to pcache.c. (CVS 5577) (check-in: a2f375fffb user: drh tags: trunk) | |
12:19 | 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) (check-in: d025866b09 user: danielk1977 tags: trunk) | |
04:41 | Move an assert() in sqlite3PcacheDirtyPage() so that it does not occur before local variable declarations. Ticket #3325. (CVS 5575) (check-in: 899fa19d1a user: danielk1977 tags: trunk) | |
Changes
Changes to src/malloc.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** Memory allocation functions used throughout sqlite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** Memory allocation functions used throughout sqlite. ** ** $Id: malloc.c,v 1.36 2008/08/21 12:19:44 danielk1977 Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> /* ** This routine runs when the memory allocator sees that the |
︙ | ︙ | |||
58 59 60 61 62 63 64 | /* ** Attempt to release up to n bytes of non-essential memory currently ** held by SQLite. An example of non-essential memory is memory used to ** cache database pages that are not currently in use. */ int sqlite3_release_memory(int n){ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT | > > | > | | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | /* ** Attempt to release up to n bytes of non-essential memory currently ** held by SQLite. An example of non-essential memory is memory used to ** cache database pages that are not currently in use. */ int sqlite3_release_memory(int n){ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT int nRet = 0; #if 0 nRet += sqlite3VdbeReleaseMemory(n); #endif nRet += sqlite3PcacheReleaseMemory(n-nRet); return nRet; #else return SQLITE_OK; #endif } /* |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.473 2008/08/21 12:19:44 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" /* ** Macros for troubleshooting. Normally turned off */ |
︙ | ︙ | |||
2449 2450 2451 2452 2453 2454 2455 | ** by the pcache layer. */ static int pagerStress(void *p){ Pager *pPager = (Pager *)p; PgHdr *pPg = sqlite3PcacheDirtyPage(pPager->pPCache); int rc = SQLITE_OK; | | > | | > > > | 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 | ** by the pcache layer. */ static int pagerStress(void *p){ Pager *pPager = (Pager *)p; PgHdr *pPg = sqlite3PcacheDirtyPage(pPager->pPCache); int rc = SQLITE_OK; if( pPg ){ assert( pPg->flags&PGHDR_DIRTY ); 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); } }else{ sqlite3PcacheMakeClean(pPg); } } return rc; } /* ** Return 1 if there is a hot journal on the given pager. |
︙ | ︙ | |||
2519 2520 2521 2522 2523 2524 2525 | } } } return rc; } | < < < < < < < < < < < < < < < | 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 | } } } return rc; } /* ** Read the content of page pPg out of the database file. */ static int readDbPage(Pager *pPager, PgHdr *pPg, Pgno pgno){ int rc; i64 offset; assert( MEMDB==0 ); |
︙ | ︙ |
Changes to src/pager.h.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite page cache ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite page cache ** 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.79 2008/08/21 12:19:44 danielk1977 Exp $ */ #ifndef _PAGER_H_ #define _PAGER_H_ /* ** If defined as non-zero, auto-vacuum is enabled by default. Otherwise |
︙ | ︙ | |||
111 112 113 114 115 116 117 | int sqlite3PagerLockingMode(Pager *, int); int sqlite3PagerJournalMode(Pager *, int); i64 sqlite3PagerJournalSizeLimit(Pager *, i64); void *sqlite3PagerTempSpace(Pager*); int sqlite3PagerSync(Pager *pPager); void sqlite3PagerAlwaysRollback(Pager *pPager); | < < < < | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | int sqlite3PagerLockingMode(Pager *, int); int sqlite3PagerJournalMode(Pager *, int); i64 sqlite3PagerJournalSizeLimit(Pager *, i64); void *sqlite3PagerTempSpace(Pager*); int sqlite3PagerSync(Pager *pPager); void sqlite3PagerAlwaysRollback(Pager *pPager); #ifdef SQLITE_HAS_CODEC void sqlite3PagerSetCodec(Pager*,void*(*)(void*,void*,Pgno,int),void*); #endif #if !defined(NDEBUG) || defined(SQLITE_TEST) Pgno sqlite3PagerPagenumber(DbPage*); int sqlite3PagerIswriteable(DbPage*); |
︙ | ︙ |
Changes to src/pcache.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2008 August 05 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file implements that page cache. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2008 August 05 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file implements that page cache. ** ** @(#) $Id: pcache.c,v 1.4 2008/08/21 12:19:44 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** A complete page cache is an instance of this structure. */ struct PCache { |
︙ | ︙ | |||
327 328 329 330 331 332 333 | if( sz<=pcache.szSlot && pcache.pFree ){ PgFreeslot *p = pcache.pFree; pcache.pFree = p->pNext; sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, sz); sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1); return (void*)p; }else{ | > > | > | 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | if( sz<=pcache.szSlot && pcache.pFree ){ PgFreeslot *p = pcache.pFree; pcache.pFree = p->pNext; sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, sz); sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1); return (void*)p; }else{ void *p; pcacheExitGlobal(); p = sqlite3Malloc(sz); pcacheEnterGlobal(); if( p ){ sz = sqlite3MallocSize(p); sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); } return p; } } |
︙ | ︙ | |||
403 404 405 406 407 408 409 | } pcacheFree(p->apSave[0]); pcacheFree(p->apSave[1]); pcacheFree(p); } /* | < | | < < < | | < < < | | > | > | < | < < > > > | < < | 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | } pcacheFree(p->apSave[0]); pcacheFree(p->apSave[1]); pcacheFree(p); } /* ** Return the number of bytes that will be returned to the heap when ** the argument is passed to pcachePageFree(). */ 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); } static PgHdr *pcacheRecycle(PCache *pCache){ PCache *pCsr; PgHdr *p = 0; assert( pcache.isInit ); assert( sqlite3_mutex_held(pcache.mutex_lru) ); 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){ |
︙ | ︙ | |||
450 451 452 453 454 455 456 | pCsr->iInUseMM = 0; } sqlite3_mutex_leave(pcache.mutex_mem2); } p = pcache.pLruTail; | < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < | 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 | pCsr->iInUseMM = 0; } sqlite3_mutex_leave(pcache.mutex_mem2); } p = pcache.pLruTail; if( p ){ pcacheRemoveFromLruList(p); pcacheRemoveFromHash(p); pcacheRemoveFromList(&p->pCache->pClean, p); /* If the always-rollback flag is set on the page being recycled, set ** the always-rollback flag on the corresponding pager. */ if( p->flags&PGHDR_ALWAYS_ROLLBACK ){ assert(p->pPager); sqlite3PagerAlwaysRollback(p->pPager); } } 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 ){ /* Allocate a new page object. */ p = pcachePageAlloc(szPage, szExtra, bPurg); } pcacheExitGlobal(); |
︙ | ︙ | |||
1137 1138 1139 1140 1141 1142 1143 | /* ** Unlock a pager-cache. */ void sqlite3PcacheUnlock(PCache *pCache){ pCache->iInUseDB--; assert( pCache->iInUseDB>=0 ); } | > > > > > > > > > > > > > > > > > > > > > > > > > > | 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 | /* ** Unlock a pager-cache. */ 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 */ |
Changes to src/pcache.h.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite page cache ** subsystem. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite page cache ** subsystem. ** ** @(#) $Id: pcache.h,v 1.2 2008/08/21 12:19:44 danielk1977 Exp $ */ #ifndef _PCACHE_H_ typedef struct PgHdr PgHdr; typedef struct PCache PCache; |
︙ | ︙ | |||
166 167 168 169 170 171 172 173 174 175 | /* Lock and unlock a pager-cache object. The PcacheLock() function may ** block if the lock is temporarily available. While a pager-cache is locked, ** the system guarantees that any configured xStress() callback will not ** be invoked by any thread other than the one holding the lock. */ void sqlite3PcacheLock(PCache *); void sqlite3PcacheUnlock(PCache *); #endif /* _PCACHE_H_ */ | > > | 166 167 168 169 170 171 172 173 174 175 176 177 | /* Lock and unlock a pager-cache object. The PcacheLock() function may ** block if the lock is temporarily available. While a pager-cache is locked, ** the system guarantees that any configured xStress() callback will not ** be invoked by any thread other than the one holding the lock. */ void sqlite3PcacheLock(PCache *); void sqlite3PcacheUnlock(PCache *); int sqlite3PcacheReleaseMemory(int); #endif /* _PCACHE_H_ */ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code use to implement APIs that are part of the ** VDBE. ** | | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code use to implement APIs that are part of the ** VDBE. ** ** $Id: vdbeapi.c,v 1.140 2008/08/21 12:19:44 danielk1977 Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #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 ** buffers eligible for release when the sqlite3_release_memory() interface is ** invoked. Access to this list is protected by the SQLITE_MUTEX_STATIC_LRU2 ** mutex. ** |
︙ | ︙ |
Changes to test/mutex1.test.
1 2 3 4 5 6 7 8 9 10 11 | # 2008 June 17 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # 2008 June 17 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # $Id: mutex1.test,v 1.12 2008/08/21 12:19:44 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl if {[info exists tester_do_binarylog]} { finish_test return |
︙ | ︙ | |||
95 96 97 98 99 100 101 | set enable_shared_cache [sqlite3_enable_shared_cache 1] ifcapable threadsafe { foreach {mode mutexes} { singlethread {} multithread {fast static_lru static_master static_mem static_mem2 static_prng } serialized {fast recursive static_lru static_master static_mem static_mem2 static_prng } } { | < < < < < | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | set enable_shared_cache [sqlite3_enable_shared_cache 1] ifcapable threadsafe { foreach {mode mutexes} { singlethread {} multithread {fast static_lru static_master static_mem static_mem2 static_prng } serialized {fast recursive static_lru static_master static_mem static_mem2 static_prng } } { do_test mutex1.2.$mode.1 { catch {db close} sqlite3_shutdown sqlite3_config $mode } SQLITE_OK |
︙ | ︙ |