-C Testing\sof\sthe\sautomatic\sTSD\sdeallocation\slogic.\s\sThe\ssqlite3_thread_cleanup()\nAPI\sis\sdocumented.\s\sThis\sshould\sclose\sticket\s#1601.\s(CVS\s2920)
-D 2006-01-11T23:40:33
+C Improve\sperformance\sby\sabout\s10%\sby\savoiding\sexcess\scalls\sto\sget\nthe\sthread-specific\sdata.\s(CVS\s2921)
+D 2006-01-12T01:25:18
F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
F src/os_common.h 78bcc34dded9b625b3c16d072b7e5b76d075a674
F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c
F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3
-F src/os_unix.c d3ec9c61a1194d3e475423298de6ce13871605a1
+F src/os_unix.c bc35a237a10c2ecb5c5b038d31d20ecb098dcc7d
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
-F src/os_win.c e372f99c4a89b9c54249a29c8c4912e5a2e67fb4
+F src/os_win.c 4ebb7e116e144d5bdfa4a0d4c31061d6f22b0736
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c a96b9c43664670576e41eac699277c7862d604d8
F src/pager.h e0acb095b3ad0bca48f2ab00c87346665643f64f
F src/server.c e425729aa7ff374637033a38ba9fd9938c432244
F src/shell.c 66b073375efbdee19045e7e0cd38b85f9aff71da
F src/sqlite.h.in 4320cff369e37897d2839d526c2b8917a2756d60
-F src/sqliteInt.h bd3fba6d7163ef402b5633191ee5d7de5b7f6e80
+F src/sqliteInt.h 34e251f02155ba30f8c9872c23fcc5ce822a66f0
F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316
F src/tclsqlite.c d650bea0248fc0a310ddc2cb94273a3a5021fddf
F src/test1.c 30ed0d4d594db0bb2beb98be7024cde1fe686f14
F src/trigger.c 694b247476d2fc0dce003af564f79e8752fc1158
F src/update.c 261d75c702c2852d1a64274d7c414485e6f2d177
F src/utf.c b7bffac4260177ae7f83c01d025fe0f5ed70ce71
-F src/util.c 8a147f96099ce716e4ee750142a8f53f1aed3286
+F src/util.c 1d751152ab36d2756deec68e576366f58b73968f
F src/vacuum.c cd56995ecea281b3ac306ef88128ebc8a2117f84
-F src/vdbe.c db592ade9a0e381f5e6a7a35a67e81c2722480b5
+F src/vdbe.c 6312ac70c72b84e99d20689a1541648f929ea6a9
F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
F src/vdbeInt.h 5451cf71f229e366ac543607c0a17f36e5737ea9
F src/vdbeapi.c afd3837cea0dec93dcb4724d073c84fa0da68e23
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 5d9c6aa964305c3f36741ff0058da5b5f3ce0d24
-R 3399b09fea32a929acfc809e2317093c
+P fb518b0ce4ddd4aaca5cccf61e651f173e735119
+R ce9b50ecb217fb792018eee2bef49d6e
U drh
-Z 938c3f3406b28a56fdbffbe4eafe6c93
+Z e741755610cebec2aa9bd0a607d8cdad
-fb518b0ce4ddd4aaca5cccf61e651f173e735119
\ No newline at end of file
+a8c74febec11eb689ca9f6b454f8c8bbadfc49d7
\ No newline at end of file
/*
-** If called with allocateFlag==1, then return a pointer to thread
+** If called with allocateFlag>1, then return a pointer to thread
** specific data for the current thread. Allocate and zero the
** thread-specific data if it does not already exist necessary.
**
** If called with allocateFlag==0, then check the current thread
-** specific data. If it exists and is all zeros, then deallocate it.
+** specific data. Return it if it exists. If it does not exist,
+** then return NULL.
+**
+** If called with allocateFlag<0, check to see if the thread specific
+** data is allocated and is all zero. If it is then deallocate it.
** Return a pointer to the thread specific data or NULL if it is
-** unallocated.
+** unallocated or gets deallocated.
*/
ThreadData *sqlite3UnixThreadSpecificData(int allocateFlag){
static const ThreadData zeroData;
}
pTsd = pthread_getspecific(key);
- if( allocateFlag ){
+ if( allocateFlag>0 ){
if( pTsd==0 ){
pTsd = sqlite3OsMalloc(sizeof(zeroData));
if( pTsd ){
TSD_COUNTER(+1);
}
}
- }else if( pTsd!=0 && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){
+ }else if( pTsd!=0 && allocateFlag<0
+ && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){
sqlite3OsFree(pTsd);
pthread_setspecific(key, 0);
TSD_COUNTER(-1);
return pTsd;
#else
static ThreadData *pTsd = 0;
- if( allocateFlag ){
+ if( allocateFlag>0 ){
if( pTsd==0 ){
pTsd = sqlite3OsMalloc( sizeof(zeroData) );
if( pTsd ){
TSD_COUNTER(+1);
}
}
- }else if( pTsd!=0 && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){
+ }else if( pTsd!=0 && allocateFlag<0
+ && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){
sqlite3OsFree(pTsd);
TSD_COUNTER(-1);
pTsd = 0;
/*
-** If called with allocateFlag==1, then return a pointer to thread
+** If called with allocateFlag>1, then return a pointer to thread
** specific data for the current thread. Allocate and zero the
** thread-specific data if it does not already exist necessary.
**
** If called with allocateFlag==0, then check the current thread
-** specific data. If it exists and is all zeros, then deallocate it.
+** specific data. Return it if it exists. If it does not exist,
+** then return NULL.
+**
+** If called with allocateFlag<0, check to see if the thread specific
+** data is allocated and is all zero. If it is then deallocate it.
** Return a pointer to the thread specific data or NULL if it is
-** unallocated.
+** unallocated or gets deallocated.
*/
ThreadData *sqlite3WinThreadSpecificData(int allocateFlag){
static int key;
sqlite3OsLeaveMutex();
}
pTsd = TlsGetValue(key);
- if( allocateFlag ){
+ if( allocateFlag>0 ){
if( !pTsd ){
pTsd = sqlite3OsMalloc( sizeof(zeroData) );
if( pTsd ){
TSD_COUNTER_INCR;
}
}
- }else if( pTsd!=0 && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){
+ }else if( pTsd!=0 && allocateFlag<0
+ && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){
sqlite3OsFree(pTsd);
TlsSetValue(key, 0);
TSD_COUNTER_DECR;
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.462 2006/01/11 21:41:22 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.463 2006/01/12 01:25:18 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
** is deallocated.
*/
struct ThreadData {
- u8 mallocFailed; /* True after a malloc() has failed */
+ int mallocFailed; /* True after a malloc() has failed */
+ int nRef; /* Number of users */
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
int nSoftHeapLimit; /* Suggested max mem allocation. No limit if <0 */
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.168 2006/01/11 21:41:22 drh Exp $
+** $Id: util.c,v 1.169 2006/01/12 01:25:18 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#define OSSIZEOF(x) sqlite3OsAllocationSize(x)
#define OSMALLOC_FAILED()
-#endif
+#endif /* SQLITE_MEMDEBUG */
/*
** End code for memory allocation system test layer.
**--------------------------------------------------------------------------*/
** is, then deallocate it.
*/
void sqlite3ReleaseThreadData(){
- sqlite3OsThreadSpecificData(0);
+ sqlite3OsThreadSpecificData(-1);
}
/*
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.523 2006/01/11 21:41:22 drh Exp $
+** $Id: vdbe.c,v 1.524 2006/01/12 01:25:18 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#ifndef NDEBUG
Mem *pStackLimit;
#endif
+ ThreadData *pTsd = sqlite3ThreadData();
if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
+ pTsd->nRef++;
assert( db->magic==SQLITE_MAGIC_BUSY );
pTos = p->pTos;
if( p->rc==SQLITE_NOMEM ){
for(pc=p->pc; rc==SQLITE_OK; pc++){
assert( pc>=0 && pc<p->nOp );
assert( pTos<=&p->aStack[pc] );
- if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto no_mem;
+ if( pTsd->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
origPc = pc;
start = hwtime();
}
rc = sqlite3VdbeHalt(p);
assert( rc==SQLITE_BUSY || rc==SQLITE_OK );
+ pTsd->nRef--;
if( rc==SQLITE_BUSY ){
p->rc = SQLITE_BUSY;
return SQLITE_BUSY;
p->popStack = pOp->p1;
p->pc = pc + 1;
p->pTos = pTos;
+ pTsd->nRef--;
return SQLITE_ROW;
}
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
(*ctx.pFunc->xFunc)(&ctx, n, apVal);
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto no_mem;
+ if( pTsd->mallocFailed ) goto no_mem;
popStack(&pTos, n);
/* If any auxilary data functions have been called by this user function,
" transaction - SQL statements in progress", (char*)0);
rc = SQLITE_ERROR;
}else if( i!=db->autoCommit ){
+ pTsd->nRef--;
if( pOp->p2 ){
assert( i==1 );
sqlite3RollbackAll(db);
p->pc = pc;
p->rc = SQLITE_BUSY;
p->pTos = pTos;
+ pTsd->nRef--;
return SQLITE_BUSY;
}
if( rc!=SQLITE_OK && rc!=SQLITE_READONLY /* && rc!=SQLITE_BUSY */ ){
p->pc = pc;
p->rc = SQLITE_BUSY;
p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */
+ pTsd->nRef--;
return SQLITE_BUSY;
}
case SQLITE_OK: {
sqlite3SafetyOff(db);
assert( db->init.busy==0 );
db->init.busy = 1;
- assert(0==sqlite3ThreadDataReadOnly()->mallocFailed);
+ assert(0==pTsd->mallocFailed);
rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
sqliteFree(zSql);
db->init.busy = 0;
sqlite3SafetyOn(db);
if( rc==SQLITE_NOMEM ){
- sqlite3ThreadData()->mallocFailed = 1;
+ pTsd->mallocFailed = 1;
goto no_mem;
}
break;
}
sqlite3VdbeHalt(p);
p->pTos = pTos;
+ pTsd->nRef--;
return rc;
/* Jump to here if a malloc() fails. It's hard to get a malloc()
*/
abort_due_to_error:
if( p->zErrMsg==0 ){
- if( sqlite3ThreadDataReadOnly()->mallocFailed ) rc = SQLITE_NOMEM;
+ if( pTsd->mallocFailed ) rc = SQLITE_NOMEM;
sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
}
goto vdbe_halt;