A unified cache is now only used for SQLITE_ENABLE_MEMORY_MANAGEMENT, or if

SQLITE_CONFIG_PAGECACHE defines a shared start-time page cache buffer and the
application is single-threaded.

FossilOrigin-Name: d5ff1d69054d51a55eff6e1979971822db7f8f30
This commit is contained in:
drh 2015-07-06 20:57:22 +00:00
parent ee70a84ea7
commit db7ae89d5b
3 changed files with 56 additions and 52 deletions

View File

@ -1,5 +1,5 @@
C Enhance\sseparate\spcache1\sto\sallocate\sa\sblock\sof\spages\sfrom\sheap\son\sstartup,\nif\spossible,\sfor\sa\s5.2%\sperformance\simprovement.
D 2015-07-06T18:54:52.424
C A\sunified\scache\sis\snow\sonly\sused\sfor\sSQLITE_ENABLE_MEMORY_MANAGEMENT,\sor\sif\nSQLITE_CONFIG_PAGECACHE\sdefines\sa\sshared\sstart-time\spage\scache\sbuffer\sand\sthe\napplication\sis\ssingle-threaded.
D 2015-07-06T20:57:22.615
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 017bf0511d1b2dd1db5e16488fbf75a17b526cbc
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -319,7 +319,7 @@ F src/pager.h 6d435f563b3f7fcae4b84433b76a6ac2730036e2
F src/parse.y 6d60dda8f8d418b6dc034f1fbccd816c459983a8
F src/pcache.c cde06aa50962595e412d497e22fd2e07878ba1f0
F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9
F src/pcache1.c 28f3434788cac24bc95f8c1af4a61cbde179ef18
F src/pcache1.c 17c392b4208ea6e1e5d220be18bcfebac07110b1
F src/pragma.c c1f4d012ea9f6b1ce52d341b2cd0ad72d560afd7
F src/pragma.h b8632d7cdda7b25323fa580e3e558a4f0d4502cc
F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1
@ -1364,10 +1364,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 6d2999afbc25b9c238e4028f637c10eaaf0ec75e
R 773f110b2d424984f83126d1917fdcbb
T *branch * pcache-bulk-local
T *sym-pcache-bulk-local *
T -sym-trunk *
P aa7341c8736732a0a59f6688cc34e78be02a7bfc
R ab876e072a5f820e07c8ea2cb7e263ca
U drh
Z a5a615d5b6a74570375077a92838726e
Z d6cf6ae811ec210c263fdd6a92d21a0f

View File

@ -1 +1 @@
aa7341c8736732a0a59f6688cc34e78be02a7bfc
d5ff1d69054d51a55eff6e1979971822db7f8f30

View File

@ -189,6 +189,7 @@ static SQLITE_WSD struct PCacheGlobal {
** The nFreeSlot and pFree values do require mutex protection.
*/
int isInit; /* True if initialized */
int separateCache; /* Use a new PGroup for each PCache */
int szSlot; /* Size of each free slot */
int nSlot; /* The number of pcache slots */
int nReserve; /* Try to keep nFreeSlot above this */
@ -362,10 +363,14 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
pCache->pFree = p->pNext;
p->pNext = 0;
}else{
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/* The group mutex must be released before pcache1Alloc() is called. This
** is because it may call sqlite3_release_memory(), which assumes that
** is because it might call sqlite3_release_memory(), which assumes that
** this mutex is not held. */
assert( pcache1.separateCache==0 );
assert( pCache->pGroup==&pcache1.grp );
pcache1LeaveMutex(pCache->pGroup);
#endif
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
pPg = pcache1Alloc(pCache->szPage);
p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
@ -378,7 +383,9 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
pPg = pcache1Alloc(pCache->szAlloc);
p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
#endif
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
pcache1EnterMutex(pCache->pGroup);
#endif
if( pPg==0 ) return 0;
p->page.pBuf = pPg;
p->page.pExtra = &p[1];
@ -392,27 +399,23 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
/*
** Free a page object allocated by pcache1AllocPage().
**
** The pointer is allowed to be NULL, which is prudent. But it turns out
** that the current implementation happens to never call this routine
** with a NULL pointer, so we mark the NULL test with ALWAYS().
*/
static void pcache1FreePage(PgHdr1 *p){
if( ALWAYS(p) ){
PCache1 *pCache = p->pCache;
assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
if( p->isBulkLocal ){
p->pNext = pCache->pFree;
pCache->pFree = p;
}else{
pcache1Free(p->page.pBuf);
PCache1 *pCache;
assert( p!=0 );
pCache = p->pCache;
assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
if( p->isBulkLocal ){
p->pNext = pCache->pFree;
pCache->pFree = p;
}else{
pcache1Free(p->page.pBuf);
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
sqlite3_free(p);
sqlite3_free(p);
#endif
}
if( pCache->bPurgeable ){
pCache->pGroup->nCurrentPage--;
}
}
if( pCache->bPurgeable ){
pCache->pGroup->nCurrentPage--;
}
}
@ -612,6 +615,29 @@ static int pcache1Init(void *NotUsed){
UNUSED_PARAMETER(NotUsed);
assert( pcache1.isInit==0 );
memset(&pcache1, 0, sizeof(pcache1));
/*
** The pcache1.separateCache variable is true if each PCache has its own
** private PGroup (mode-1). pcache1.separateCache is false if the single
** PGroup in pcache1.grp is used for all page caches (mode-2).
**
** * Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT
**
** * Use a unified cache in single-threaded applications that have
** configured a start-time buffer for use as page-cache memory using
** sqlite3_config(SQLITE_CONFIG_PAGECACHE, pBuf, sz, N) with non-NULL
** pBuf argument.
**
** * Otherwise use separate caches (mode-1)
*/
#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT)
pcache1.separateCache = 0;
#else
pcache1.separateCache = sqlite3GlobalConfig.pPage==0
|| sqlite3GlobalConfig.bCoreMutex>0;
#endif
#if SQLITE_THREADSAFE
if( sqlite3GlobalConfig.bCoreMutex ){
pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
@ -647,31 +673,13 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
PGroup *pGroup; /* The group the new page cache will belong to */
int sz; /* Bytes of memory required to allocate the new cache */
/*
** The separateCache variable is true if each PCache has its own private
** PGroup. In other words, separateCache is true for mode (1) where no
** mutexing is required.
**
** * Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT
**
** * Always use a unified cache in single-threaded applications
**
** * Otherwise (if multi-threaded and ENABLE_MEMORY_MANAGEMENT is off)
** use separate caches (mode-1)
*/
#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0
const int separateCache = 0;
#else
int separateCache = sqlite3GlobalConfig.bCoreMutex>0;
#endif
assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 );
assert( szExtra < 300 );
sz = sizeof(PCache1) + sizeof(PGroup)*separateCache;
sz = sizeof(PCache1) + sizeof(PGroup)*pcache1.separateCache;
pCache = (PCache1 *)sqlite3MallocZero(sz);
if( pCache ){
if( separateCache ){
if( pcache1.separateCache ){
pGroup = (PGroup*)&pCache[1];
pGroup->mxPinned = 10;
}else{
@ -690,10 +698,9 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
}
pcache1LeaveMutex(pGroup);
if( separateCache
&& sqlite3GlobalConfig.szPage==0
&& sqlite3GlobalConfig.nPage!=0
){
/* Try to initialize the local bulk pagecache line allocation if using
** separate caches and if nPage!=0 */
if( pcache1.separateCache && sqlite3GlobalConfig.nPage!=0 ){
int szBulk;
char *zBulk;
sqlite3BeginBenignMalloc();