]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix soft-heap-limit related test suite failures. (CVS 5582)
authordanielk1977 <danielk1977@noemail.net>
Thu, 21 Aug 2008 15:54:01 +0000 (15:54 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Thu, 21 Aug 2008 15:54:01 +0000 (15:54 +0000)
FossilOrigin-Name: 2091d9a5260b1d7e27ff5ca93e60dae1e3b12081

manifest
manifest.uuid
src/pcache.c
test/malloc5.test
test/permutations.test

index b97f1daba657874b2fe723f0e9420403212a2fbb..6b57f59827b62c7a434a2780cc200794899d03de 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Increase\sthe\sversion\snumber\sin\spreparation\sfor\sthe\snext\srelease.\s(CVS\s5581)
-D 2008-08-21T15:13:43
+C Fix\ssoft-heap-limit\srelated\stest\ssuite\sfailures.\s(CVS\s5582)
+D 2008-08-21T15:54:01
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in 0b1c022000f55221454a7846022f11674d8024bf
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -138,7 +138,7 @@ F src/os_win.c aefe9ee26430678a19a058a874e4e2bd91398142
 F src/pager.c 3a4358c72c9c8415e8648001c776857e6952e2b4
 F src/pager.h 3778bea71dfb9658b6c94394e18db4a5b27e6ded
 F src/parse.y d0f76d2cb8d6883d5600dc20beb961a6022b94b8
-F src/pcache.c 54d03c3550893582451c476731a3d4b6b682f7b8
+F src/pcache.c 4668410008dda89ff5f0eb62b887cfb5e13903eb
 F src/pcache.h aef1dedd7ff6186f27052a2509fff437a8906977
 F src/pragma.c f5b271b090af7fcedd308d7c5807a5503f7a853d
 F src/prepare.c c197041e0c4770672cda75e6bfe10242f885e510
@@ -402,7 +402,7 @@ F test/main.test 8d77c161757ef7d96eaff0413daa7120c3b316fe
 F test/malloc.test 69f5bb5a13b24edb1322fc1f42894f9d2f6446b1
 F test/malloc3.test 094f8195fe8e409bd4da0f1d769f7745faec62c8
 F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
-F test/malloc5.test 1a68e56e513eab54d8c4cd1b769ff1d14e3f99f4
+F test/malloc5.test 8b18857f37c1c409b914789934aeb1346b778b3a
 F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
 F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
 F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
@@ -445,7 +445,7 @@ F test/pager2.test 070983b89a308adaba525a2f9c1ba0592c72fa3d
 F test/pager3.test 2323bf27fd5bd887b580247e5bce500ceee994b4
 F test/pageropt.test 3ee6578891baaca967f0bd349e4abfa736229e1a
 F test/pagesize.test e0a8b3fe80f8b8e808d94a00734c7a18c76c407e
-F test/permutations.test 4ad59e4489255b025aac0cc661789d35a83d87ec
+F test/permutations.test 1f7ead8d56d62633b2dd00c26868db35f0b3dcdf
 F test/pragma.test b55931bbd5dd543e56fd942dbf4b7439619b09a6
 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
 F test/printf.test 262a5acd3158f788e9bdf7f18d718f3af32ff6ef
@@ -623,7 +623,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 8593218c7c8016fbdbcc223db951751eaba9c0dd
-R 316e5dae58950571a5d41225469e48e2
-U drh
-Z 79d80137c3262f0c6af4b82ef771a790
+P d68dad73d0a85c6213a96982d0366c790871b693
+R b1b9ce7ac833bb03734065aa230b3a65
+U danielk1977
+Z 442c477497b5c11bc6fcf9ea22d419f7
index 055d66f1e0ab1908ca7d947b463bb9d124867f19..42cb63edadcc96ed773746686efb8524b566562c 100644 (file)
@@ -1 +1 @@
-d68dad73d0a85c6213a96982d0366c790871b693
\ No newline at end of file
+2091d9a5260b1d7e27ff5ca93e60dae1e3b12081
\ No newline at end of file
index 18688e69aab713ae8eeb4bea2b3c5b312872b0c6..7778212de6b426b767ce91c9308f6cb06339190c 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file implements that page cache.
 **
-** @(#) $Id: pcache.c,v 1.5 2008/08/21 12:32:12 drh Exp $
+** @(#) $Id: pcache.c,v 1.6 2008/08/21 15:54:01 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 
@@ -97,6 +97,9 @@ static struct PCacheGlobal {
 ** Before the xStress callback of a pager-cache (PCache) is invoked, the
 ** SQLITE_MUTEX_STATIC_MEM2 mutex is obtained and the SQLITE_MUTEX_STATIC_LRU 
 ** mutex released (in that order) before making the call.
+**
+** Deadlock within the module is avoided by never blocking on the MEM2 
+** mutex while the LRU mutex is held.
 */
 
 #define pcacheEnterGlobal() sqlite3_mutex_enter(pcache.mutex_lru)
@@ -322,7 +325,7 @@ void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
 ** and use an element from it first if available.  If nothing is available
 ** in the page cache memory pool, go to the general purpose memory allocator.
 */
-void *pcacheMalloc(int sz){
+void *pcacheMalloc(int sz, PCache *pCache){
   assert( sqlite3_mutex_held(pcache.mutex_lru) );
   if( sz<=pcache.szSlot && pcache.pFree ){
     PgFreeslot *p = pcache.pFree;
@@ -332,9 +335,21 @@ void *pcacheMalloc(int sz){
     return (void*)p;
   }else{
     void *p;
+
+    /* Allocate a new buffer using sqlite3Malloc. Before doing so, exit the
+    ** global pcache mutex and unlock the pager-cache object pCache. This is 
+    ** so that if the attempt to allocate a new buffer causes the the 
+    ** configured soft-heap-limit to be breached, it will be possible to
+    ** reclaim memory from this pager-cache. Because sqlite3PcacheLock() 
+    ** might block on the MEM2 mutex, it has to be called before re-entering
+    ** the global LRU mutex.
+    */
     pcacheExitGlobal();
+    sqlite3PcacheUnlock(pCache);
     p = sqlite3Malloc(sz);
+    sqlite3PcacheLock(pCache);
     pcacheEnterGlobal();
+
     if( p ){
       sz = sqlite3MallocSize(p);
       sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
@@ -345,7 +360,7 @@ void *pcacheMalloc(int sz){
 void *sqlite3PageMalloc(sz){
   void *p;
   pcacheEnterGlobal();
-  p = pcacheMalloc(sz);
+  p = pcacheMalloc(sz, 0);
   pcacheExitGlobal();
   return p;
 }
@@ -377,18 +392,17 @@ void sqlite3PageFree(void *p){
 /*
 ** Allocate a new page.
 */
-static PgHdr *pcachePageAlloc(int szPage, int szExtra, int bPurgeable){
+static PgHdr *pcachePageAlloc(PCache *pCache){
   PgHdr *p;
-  int sz = sizeof(*p) + szPage + szExtra;
+  int sz = sizeof(*p) + pCache->szPage + pCache->szExtra;
   assert( sqlite3_mutex_held(pcache.mutex_lru) );
-  p = pcacheMalloc( sz );
+  p = pcacheMalloc(sz, pCache);
   if( p==0 ) return 0;
   memset(p, 0, sizeof(PgHdr));
   p->pData = (void*)&p[1];
-  p->pExtra = (void*)&((char*)p->pData)[szPage];
-
+  p->pExtra = (void*)&((char*)p->pData)[pCache->szPage];
   pcache.nPage++;
-  if( bPurgeable ){
+  if( pCache->bPurgeable ){
     pcache.nPurgeable++;
   }
 
@@ -501,8 +515,7 @@ static PgHdr *pcacheRecycleOrAlloc(PCache *pCache){
   }
 
   if( !p ){
-    /* Allocate a new page object. */
-    p = pcachePageAlloc(szPage, szExtra, bPurg);
+    p = pcachePageAlloc(pCache);
   }
 
   pcacheExitGlobal();
@@ -566,6 +579,7 @@ void sqlite3PcacheOpen(
   }
 
   /* Add the new pager-cache to the list of caches starting at pcache.pAll */
+  assert( sqlite3_mutex_notheld(pcache.mutex_lru) );
   sqlite3_mutex_enter(pcache.mutex_mem2);
   p->pNextAll = pcache.pAll;
   if( pcache.pAll ){
@@ -858,6 +872,7 @@ void sqlite3PcacheClose(PCache *pCache){
   ** all such structures headed by pcache.pAll. This required the
   ** MUTEX_STATIC_MEM2 mutex.
   */
+  assert( sqlite3_mutex_notheld(pcache.mutex_lru) );
   sqlite3_mutex_enter(pcache.mutex_mem2);
   assert(pCache==pcache.pAll || pCache->pPrevAll);
   assert(pCache->pNextAll==0 || pCache->pNextAll->pPrevAll==pCache);
@@ -1151,13 +1166,16 @@ void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
 ** Lock a pager-cache.
 */
 void sqlite3PcacheLock(PCache *pCache){
-  pCache->iInUseDB++;
-  if( pCache->iInUseMM && pCache->iInUseDB==1 ){
-    pCache->iInUseDB = 0;
-    sqlite3_mutex_enter(pcache.mutex_mem2);
-    assert( pCache->iInUseMM==0 && pCache->iInUseDB==0 );
-    pCache->iInUseDB = 1;
-    sqlite3_mutex_leave(pcache.mutex_mem2);
+  if( pCache ){
+    assert( sqlite3_mutex_notheld(pcache.mutex_lru) );
+    pCache->iInUseDB++;
+    if( pCache->iInUseMM && pCache->iInUseDB==1 ){
+      pCache->iInUseDB = 0;
+      sqlite3_mutex_enter(pcache.mutex_mem2);
+      assert( pCache->iInUseMM==0 && pCache->iInUseDB==0 );
+      pCache->iInUseDB = 1;
+      sqlite3_mutex_leave(pcache.mutex_mem2);
+    }
   }
 }
 
@@ -1165,8 +1183,10 @@ void sqlite3PcacheLock(PCache *pCache){
 ** Unlock a pager-cache.
 */
 void sqlite3PcacheUnlock(PCache *pCache){
-  pCache->iInUseDB--;
-  assert( pCache->iInUseDB>=0 );
+  if( pCache ){
+    pCache->iInUseDB--;
+    assert( pCache->iInUseDB>=0 );
+  }
 }
 
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
index 22f9237df4c8d15daec25218585f69f2585ca51c..550cb03dcc16cbd892577108162538b50c346929 100644 (file)
@@ -12,7 +12,7 @@
 # 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.18 2008/02/18 22:24:58 drh Exp $
+# $Id: malloc5.test,v 1.19 2008/08/21 15:54:01 danielk1977 Exp $
 
 #---------------------------------------------------------------------------
 # NOTES ON EXPECTED BEHAVIOUR
@@ -206,7 +206,7 @@ do_test malloc5-4.1 {
 } {1}
 do_test malloc5-4.2 {
   sqlite3_release_memory
-  sqlite3_soft_heap_limit 100000
+  sqlite3_soft_heap_limit 110000
   sqlite3_memory_highwater 1
   execsql {BEGIN;}
   for {set i 0} {$i < 10000} {incr i} {
@@ -231,7 +231,7 @@ do_test malloc5-4.2 {
   # the problem are the calls to sqlite3_malloc() inserted into selected
   # sqlite3OsXXX() functions in test builds.
   #
-  expr $nMaxBytes <= 100100
+  expr $nMaxBytes <= 110100
 } {1}
 do_test malloc5-4.3 {
   # Check that the content of table abc is at least roughly as expected.
@@ -296,6 +296,9 @@ do_test malloc5-6.1.1 {
   execsql {
     PRAGMA page_size=1024;
     PRAGMA default_cache_size=10;
+  }
+  execsql {
+    PRAGMA temp_store = memory;
     BEGIN;
     CREATE TABLE abc(a PRIMARY KEY, b, c);
     INSERT INTO abc VALUES(randstr(50,50), randstr(75,75), randstr(100,100));
@@ -325,22 +328,22 @@ do_test malloc5-6.1.2 {
 do_test malloc5-6.2.1 {
   execsql { SELECT * FROM abc } db2
   execsql {SELECT * FROM abc} db
-  list [nPage db] [nPage db2]
-} {10 10}
+  expr [nPage db] + [nPage db2]
+} {20}
+
 do_test malloc5-6.2.2 {
   # If we now try to reclaim some memory, it should come from the db2 cache.
   sqlite3_release_memory 3000
-  list [nPage db] [nPage db2]
-} {17}
+  expr [nPage db] + [nPage db2]
+} {17}
 do_test malloc5-6.2.3 {
   # Access the db2 cache again, so that all the db2 pages have been used
   # more recently than all the db pages. Then try to reclaim 3000 bytes.
   # This time, 3 pages should be pulled from the db cache.
   execsql { SELECT * FROM abc } db2
   sqlite3_release_memory 3000
-  list [nPage db] [nPage db2]
-} {7 10}
-
+  expr [nPage db] + [nPage db2]
+} {17}
 
 do_test malloc5-6.3.1 {
   # Now open a transaction and update 2 pages in the db2 cache. Then
@@ -356,8 +359,8 @@ do_test malloc5-6.3.1 {
     WHERE rowid = 1 OR rowid = (SELECT max(rowid) FROM abc);
   } db2
   execsql { SELECT * FROM abc } db
-  list [nPage db] [nPage db2]
-} {10 10}
+  expr [nPage db] + [nPage db2]
+} {20}
 do_test malloc5-6.3.2 {
   # Try to release 7700 bytes. This should release all the 
   # non-dirty pages held by db2.
index 8aee99f19ed18fd0b02e501ef1fee0618e52f12b..f8cc0b0a3741a226ff789c9cea19c18cb15d7044 100644 (file)
@@ -9,7 +9,7 @@
 #
 #***********************************************************************
 #
-# $Id: permutations.test,v 1.20 2008/08/01 18:47:02 drh Exp $
+# $Id: permutations.test,v 1.21 2008/08/21 15:54:01 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -141,6 +141,9 @@ proc run_tests {name args} {
 #
 run_tests "memsubsys1" -description {
   Tests using pre-allocated page and scratch blocks
+} -exclude {
+  ioerr5.test
+  malloc5.test
 } -initialize {
   catch {db close}
   sqlite3_shutdown