Index: src/malloc.c ================================================================== --- src/malloc.c +++ src/malloc.c @@ -308,12 +308,14 @@ ** Each thread may only have a single outstanding allocation from ** xScratchMalloc(). We verify this constraint in the single-threaded ** case by setting scratchAllocOut to 1 when an allocation ** is outstanding clearing it when the allocation is freed. */ +#ifndef SQLITE_DISABLE_SCRATCH_MALLOC #if SQLITE_THREADSAFE==0 && !defined(NDEBUG) static int scratchAllocOut = 0; +#endif #endif /* ** Allocate memory that is to be used and released right away. @@ -322,10 +324,13 @@ ** routine is intended to get memory to old large transient data ** structures that would not normally fit on the stack of an ** embedded processor. */ void *sqlite3ScratchMalloc(int n){ +#ifdef SQLITE_DISABLE_SCRATCH_MALLOC + return sqlite3Malloc(n); +#else void *p; assert( n>0 ); sqlite3_mutex_enter(mem0.mutex); sqlite3StatusHighwater(SQLITE_STATUS_SCRATCH_SIZE, n); @@ -357,12 +362,16 @@ assert( scratchAllocOut==0 ); if( p ) scratchAllocOut++; #endif return p; +#endif /* SQLITE_DISABLE_SCRATCH_MALLOC */ } void sqlite3ScratchFree(void *p){ +#ifdef SQLITE_DISABLE_SCRATCH_MALLOC + sqlite3_free(p); +#else if( p ){ #if SQLITE_THREADSAFE==0 && !defined(NDEBUG) /* Verify that no more than two scratch allocation per thread ** is outstanding at one time. (This is only checked in the @@ -399,10 +408,11 @@ }else{ sqlite3GlobalConfig.m.xFree(p); } } } +#endif /* SQLITE_DISABLE_SCRATCH_MALLOC */ } /* ** TRUE if p is a lookaside memory allocation from db */ Index: src/mutex_unix.c ================================================================== --- src/mutex_unix.c +++ src/mutex_unix.c @@ -40,10 +40,13 @@ */ struct sqlite3_mutex { pthread_mutex_t mutex; /* Mutex controlling the lock */ #if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) int id; /* Mutex type */ +#endif +#ifdef SQLITE_COUNT_MUTEX_DELAYS + u32 nCollide; #endif #if SQLITE_MUTEX_NREF volatile int nRef; /* Number of entrances */ volatile pthread_t owner; /* Thread that is within this mutex */ int trace; /* True to trace changes */ @@ -219,10 +222,15 @@ #if SQLITE_ENABLE_API_ARMOR if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ) #endif { pthread_mutex_destroy(&p->mutex); +#if SQLITE_COUNT_MUTEX_DELAYS + if( p->nCollide ){ + printf("%d mutex delays for %p\n", p->nCollide, (void*)p); + } +#endif sqlite3_free(p); } #ifdef SQLITE_ENABLE_API_ARMOR else{ (void)SQLITE_MISUSE_BKPT; @@ -267,11 +275,18 @@ } } #else /* Use the built-in recursive mutexes if they are available. */ +#if SQLITE_COUNT_MUTEX_DELAYS + if( pthread_mutex_trylock(&p->mutex) ){ + p->nCollide++; + pthread_mutex_lock(&p->mutex); + } +#else pthread_mutex_lock(&p->mutex); +#endif #if SQLITE_MUTEX_NREF assert( p->nRef>0 || p->owner==0 ); p->owner = pthread_self(); p->nRef++; #endif Index: src/pcache1.c ================================================================== --- src/pcache1.c +++ src/pcache1.c @@ -249,11 +249,11 @@ void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ if( pcache1.isInit ){ PgFreeslot *p; if( pBuf==0 ) sz = n = 0; sz = ROUNDDOWN8(sz); - pcache1.szSlot = sz; + pcache1.szSlot = n ? sz : 0; pcache1.nSlot = pcache1.nFreeSlot = n; pcache1.nReserve = n>90 ? 10 : (n/10 + 1); pcache1.pStart = pBuf; pcache1.pFree = 0; pcache1.bUnderPressure = 0;