Index: src/malloc.c ================================================================== --- src/malloc.c +++ src/malloc.c @@ -374,16 +374,20 @@ assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) ); assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_SCRATCH) ); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); if( sqlite3GlobalConfig.bMemstat ){ int iSize = sqlite3MallocSize(p); +#ifndef SQLITE_ATOMIC_STATUS_DOWN sqlite3_mutex_enter(mem0.mutex); +#endif sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize); sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize); sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); sqlite3GlobalConfig.m.xFree(p); +#ifndef SQLITE_ATOMIC_STATUS_DOWN sqlite3_mutex_leave(mem0.mutex); +#endif }else{ sqlite3GlobalConfig.m.xFree(p); } } } @@ -438,15 +442,19 @@ void sqlite3_free(void *p){ if( p==0 ) return; /* IMP: R-49053-54554 */ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); if( sqlite3GlobalConfig.bMemstat ){ +#ifndef SQLITE_ATOMIC_STATUS_DOWN sqlite3_mutex_enter(mem0.mutex); +#endif sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p)); sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); sqlite3GlobalConfig.m.xFree(p); +#ifndef SQLITE_ATOMIC_STATUS_DOWN sqlite3_mutex_leave(mem0.mutex); +#endif }else{ sqlite3GlobalConfig.m.xFree(p); } } Index: src/sqliteInt.h ================================================================== --- src/sqliteInt.h +++ src/sqliteInt.h @@ -226,10 +226,19 @@ # define SQLITE_NOINLINE __declspec(noinline) #else # define SQLITE_NOINLINE #endif +/* +** The SQLITE_ATOMIC_STATUS_DOWN macro is defined if and only if +** the sqlite3StatusDown() function is threadsafe. +*/ +#if !defined(SQLITE_DISABLE_INTRINSIC) \ + && defined(__GNUC__) && GCC_VERSION>=4004000 +# define SQLITE_ATOMIC_STATUS_DOWN 1 +#endif + /* ** Make sure that the compiler intrinsics we desire are enabled when ** compiling with an appropriate version of MSVC unless prevented by ** the SQLITE_DISABLE_INTRINSIC define. */ Index: src/status.c ================================================================== --- src/status.c +++ src/status.c @@ -98,15 +98,20 @@ } } void sqlite3StatusDown(int op, int N){ wsdStatInit; assert( N>=0 ); + assert( op>=0 && op=4004000 + (void)__sync_fetch_and_sub(&wsdStat.nowValue[op], N); +#else assert( op>=0 && op=0 && op