From: drh Date: Tue, 29 Aug 2017 20:21:12 +0000 (+0000) Subject: Faster memory allocation from lookaside by not trying to keep track of the X-Git-Tag: version-3.21.0~116 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=52fb8e194564a83028c8d1ccb0a159806fb63029;p=thirdparty%2Fsqlite.git Faster memory allocation from lookaside by not trying to keep track of the number of outstanding allocations, and rather computing that value only when requested. FossilOrigin-Name: a06263f1efd2d45eac88b8d59e8fe8e458670fa3808c795feaa7f247fc36cbe9 --- diff --git a/manifest b/manifest index c1fc26d824..a460f66c1f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--enable-update-limit\soption\sto\sthe\s./configure\sscript. -D 2017-08-28T17:00:12.028 +C Faster\smemory\sallocation\sfrom\slookaside\sby\snot\strying\sto\skeep\strack\sof\sthe\nnumber\sof\soutstanding\sallocations,\sand\srather\scomputing\sthat\svalue\sonly\nwhen\srequested. +D 2017-08-29T20:21:12.167 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -402,7 +402,7 @@ F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca F src/btree.c 1033b88fe50aba7d364b5a19666a9a274caa8d4c25ab7f3914221997b46af44a F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09 F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc -F src/build.c b47a0320c6d237718b8f493ac97d37d1071bce12aca668b15219187150c41295 +F src/build.c e71e96a67daf3d1dd23188423e66cd6af38017e2ec73fead5d2b57da2d3c7e16 F src/callback.c 28a8ede982fde4129b828350f78f2c01fe7d12c74d1a0a05d7108ab36f308688 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0 @@ -421,8 +421,8 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c d2d1bf12d2b5382450620d7cede84c7ffe57e6a89fa9a908f1aba68df2731cd9 F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e F src/loadext.c 20865b183bb8a3723d59cf1efffc3c50217eb452c1021d077b908c94da26b0b2 -F src/main.c 227a83d3f840d55e40360a1a8370c120f1466ea7d73b1fffb74b8f59ad0f4046 -F src/malloc.c e069cec00407e029d71fbc9440ebbb5833a629416324b592ade8fed93b045c83 +F src/main.c 48a641949ce76c857b8771230c4304501287285714ea796f803b4178629ed560 +F src/malloc.c a02c9e69bc76bee0f639416b947a946412890b606301454727feadcb313536d6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -462,9 +462,9 @@ F src/shell.c.in af3fb9eabdc0a95beace2f760597d213be0988c974eca116208eb220cd24469 F src/sqlite.h.in f18eef5b101d5f33f98ca43decb1f025c1b629f091ad77fe2190128e93938a5a F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a1fd3aa82f967da436164e0728a7d6841651fd0c6e27b9044e0eb9f6c8462e47 -F src/sqliteInt.h 9a283ecf57bb81e0040d243d56e91beae76f6d5762b3ac33c7f3ec6076a71d99 +F src/sqliteInt.h 60295f5f909e32aef1961075a8fa98df19335a4b7792b4a0b897f1d8789681c9 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b -F src/status.c 90450a491f3f59f6978ca9832023c31238f592064e405eeda971f3c0829564eb +F src/status.c 9737ed017279a9e0c5da748701c3c7bf1e8ae0dae459aad20dd64fcff97a7e35 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/tclsqlite.c 487951d81f9704800fd9f0ffdaa2f935a83ccb6be3575c2c4ef83e4789b4c828 F src/test1.c 8513b17ca4a7a9ba28748535d178b6e472ec7394ae0eea53907f2d3bcdbab2df @@ -1651,7 +1651,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1ba051e34d7512ab5e8fc969c1b5aaaf827b8e6493ba4235895257aca78b500f -R 7e1ed169d6d4a03a64afe06fcba95957 +P 64a8ae68381b7fbb29b659901ca7ce8d50510e4753758d5761f7e41539288cef +R bf9afa7c8e223eb9e939beb0ed77930c U drh -Z 13247c5e6bbeac642354740051347480 +Z 4dae0b64b90b0b3580ad9499179d8a8f diff --git a/manifest.uuid b/manifest.uuid index 09eebfb4e5..9d0521f6c3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -64a8ae68381b7fbb29b659901ca7ce8d50510e4753758d5761f7e41539288cef \ No newline at end of file +a06263f1efd2d45eac88b8d59e8fe8e458670fa3808c795feaa7f247fc36cbe9 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 05126f6260..6cd23c2abf 100644 --- a/src/build.c +++ b/src/build.c @@ -598,13 +598,16 @@ void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){ */ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ Index *pIndex, *pNext; - TESTONLY( int nLookaside; ) /* Used to verify lookaside not used for schema */ +#ifdef SQLITE_DEBUG /* Record the number of outstanding lookaside allocations in schema Tables ** prior to doing any free() operations. Since schema Tables do not use ** lookaside, this number should not change. */ - TESTONLY( nLookaside = (db && (pTable->tabFlags & TF_Ephemeral)==0) ? - db->lookaside.nOut : 0 ); + int nLookaside = 0; + if( db && (pTable->tabFlags & TF_Ephemeral)==0 ){ + nLookaside = sqlite3LookasideUsed(db, 0); + } +#endif /* Delete all indices associated with this table. */ for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){ @@ -638,7 +641,7 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ sqlite3DbFree(db, pTable); /* Verify that no lookaside memory was used by schema tables */ - assert( nLookaside==0 || nLookaside==db->lookaside.nOut ); + assert( nLookaside==0 || nLookaside==sqlite3LookasideUsed(db,0) ); } void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ /* Do not delete the table until the reference count reaches zero. */ diff --git a/src/main.c b/src/main.c index 212f7d6b5f..168ce851f6 100644 --- a/src/main.c +++ b/src/main.c @@ -658,7 +658,8 @@ int sqlite3_config(int op, ...){ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ #ifndef SQLITE_OMIT_LOOKASIDE void *pStart; - if( db->lookaside.nOut ){ + + if( sqlite3LookasideUsed(db,0)>0 ){ return SQLITE_BUSY; } /* Free any existing lookaside buffer for this handle before @@ -686,16 +687,18 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ pStart = pBuf; } db->lookaside.pStart = pStart; + db->lookaside.pInit = 0; db->lookaside.pFree = 0; db->lookaside.sz = (u16)sz; if( pStart ){ int i; LookasideSlot *p; assert( sz > (int)sizeof(LookasideSlot*) ); + db->lookaside.nSlot = cnt; p = (LookasideSlot*)pStart; for(i=cnt-1; i>=0; i--){ - p->pNext = db->lookaside.pFree; - db->lookaside.pFree = p; + p->pNext = db->lookaside.pInit; + db->lookaside.pInit = p; p = (LookasideSlot*)&((u8*)p)[sz]; } db->lookaside.pEnd = p; @@ -706,6 +709,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ db->lookaside.pEnd = db; db->lookaside.bDisable = 1; db->lookaside.bMalloced = 0; + db->lookaside.nSlot = 0; } #endif /* SQLITE_OMIT_LOOKASIDE */ return SQLITE_OK; @@ -1225,7 +1229,7 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ sqlite3_mutex_leave(db->mutex); db->magic = SQLITE_MAGIC_CLOSED; sqlite3_mutex_free(db->mutex); - assert( db->lookaside.nOut==0 ); /* Fails on a lookaside memory leak */ + assert( sqlite3LookasideUsed(db,0)==0 ); if( db->lookaside.bMalloced ){ sqlite3_free(db->lookaside.pStart); } diff --git a/src/malloc.c b/src/malloc.c index 78a50b49c5..b750f6e72f 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -354,7 +354,6 @@ void sqlite3DbFreeNN(sqlite3 *db, void *p){ #endif pBuf->pNext = db->lookaside.pFree; db->lookaside.pFree = pBuf; - db->lookaside.nOut--; return; } } @@ -515,16 +514,16 @@ void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){ assert( db->mallocFailed==0 ); if( n>db->lookaside.sz ){ db->lookaside.anStat[1]++; - }else if( (pBuf = db->lookaside.pFree)==0 ){ - db->lookaside.anStat[2]++; - }else{ + }else if( (pBuf = db->lookaside.pFree)!=0 ){ db->lookaside.pFree = pBuf->pNext; - db->lookaside.nOut++; db->lookaside.anStat[0]++; - if( db->lookaside.nOut>db->lookaside.mxOut ){ - db->lookaside.mxOut = db->lookaside.nOut; - } return (void*)pBuf; + }else if( (pBuf = db->lookaside.pInit)!=0 ){ + db->lookaside.pInit = pBuf->pNext; + db->lookaside.anStat[0]++; + return (void*)pBuf; + }else{ + db->lookaside.anStat[2]++; } }else if( db->mallocFailed ){ return 0; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 55a8efe214..1c1879a922 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1245,9 +1245,9 @@ struct Lookaside { u32 bDisable; /* Only operate the lookaside when zero */ u16 sz; /* Size of each buffer in bytes */ u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ - int nOut; /* Number of buffers currently checked out */ - int mxOut; /* Highwater mark for nOut */ - int anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ + u32 nSlot; /* Number of lookaside slots allocated */ + u32 anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ + LookasideSlot *pInit; /* List of buffers not previously used */ LookasideSlot *pFree; /* List of available buffers */ void *pStart; /* First byte of available memory space */ void *pEnd; /* First byte past end of available space */ @@ -3575,6 +3575,7 @@ sqlite3_int64 sqlite3StatusValue(int); void sqlite3StatusUp(int, int); void sqlite3StatusDown(int, int); void sqlite3StatusHighwater(int, int); +int sqlite3LookasideUsed(sqlite3*,int*); /* Access to mutexes used by sqlite3_status() */ sqlite3_mutex *sqlite3Pcache1Mutex(void); diff --git a/src/status.c b/src/status.c index b783b395d3..6e5b0e573b 100644 --- a/src/status.c +++ b/src/status.c @@ -170,6 +170,28 @@ int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){ return rc; } +/* +** Return the number of LookasideSlot elements on the linked list +*/ +static u32 countLookasideSlots(LookasideSlot *p){ + u32 cnt = 0; + while( p ){ + p = p->pNext; + cnt++; + } + return cnt; +} + +/* +** Count the number of slots of lookaside memory that are outstanding +*/ +int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){ + u32 nInit = countLookasideSlots(db->lookaside.pInit); + u32 nFree = countLookasideSlots(db->lookaside.pFree); + if( pHighwater ) *pHighwater = db->lookaside.nSlot - nInit; + return db->lookaside.nSlot - (nInit+nFree); +} + /* ** Query status information for a single database connection */ @@ -189,10 +211,15 @@ int sqlite3_db_status( sqlite3_mutex_enter(db->mutex); switch( op ){ case SQLITE_DBSTATUS_LOOKASIDE_USED: { - *pCurrent = db->lookaside.nOut; - *pHighwater = db->lookaside.mxOut; + *pCurrent = sqlite3LookasideUsed(db, pHighwater); if( resetFlag ){ - db->lookaside.mxOut = db->lookaside.nOut; + LookasideSlot *p = db->lookaside.pFree; + if( p ){ + while( p->pNext ) p = p->pNext; + p->pNext = db->lookaside.pInit; + db->lookaside.pInit = db->lookaside.pFree; + db->lookaside.pFree = 0; + } } break; }