Index: third_party/sqlite/src/src/status.c |
diff --git a/third_party/sqlite/src/src/status.c b/third_party/sqlite/src/src/status.c |
index 79a8001b8af07081243bea966c2677e95189ce21..69f92ff7c624ddb50e395d4459e8b6ca48c4310e 100644 |
--- a/third_party/sqlite/src/src/status.c |
+++ b/third_party/sqlite/src/src/status.c |
@@ -19,12 +19,34 @@ |
/* |
** Variables in which to record status information. |
*/ |
+#if SQLITE_PTRSIZE>4 |
+typedef sqlite3_int64 sqlite3StatValueType; |
+#else |
+typedef u32 sqlite3StatValueType; |
+#endif |
typedef struct sqlite3StatType sqlite3StatType; |
static SQLITE_WSD struct sqlite3StatType { |
- int nowValue[10]; /* Current value */ |
- int mxValue[10]; /* Maximum value */ |
+ sqlite3StatValueType nowValue[10]; /* Current value */ |
+ sqlite3StatValueType mxValue[10]; /* Maximum value */ |
} sqlite3Stat = { {0,}, {0,} }; |
+/* |
+** Elements of sqlite3Stat[] are protected by either the memory allocator |
+** mutex, or by the pcache1 mutex. The following array determines which. |
+*/ |
+static const char statMutex[] = { |
+ 0, /* SQLITE_STATUS_MEMORY_USED */ |
+ 1, /* SQLITE_STATUS_PAGECACHE_USED */ |
+ 1, /* SQLITE_STATUS_PAGECACHE_OVERFLOW */ |
+ 0, /* SQLITE_STATUS_SCRATCH_USED */ |
+ 0, /* SQLITE_STATUS_SCRATCH_OVERFLOW */ |
+ 0, /* SQLITE_STATUS_MALLOC_SIZE */ |
+ 0, /* SQLITE_STATUS_PARSER_STACK */ |
+ 1, /* SQLITE_STATUS_PAGECACHE_SIZE */ |
+ 0, /* SQLITE_STATUS_SCRATCH_SIZE */ |
+ 0, /* SQLITE_STATUS_MALLOC_COUNT */ |
+}; |
+ |
/* The "wsdStat" macro will resolve to the status information |
** state vector. If writable static data is unsupported on the target, |
@@ -41,58 +63,113 @@ static SQLITE_WSD struct sqlite3StatType { |
#endif |
/* |
-** Return the current value of a status parameter. |
+** Return the current value of a status parameter. The caller must |
+** be holding the appropriate mutex. |
*/ |
-int sqlite3StatusValue(int op){ |
+sqlite3_int64 sqlite3StatusValue(int op){ |
wsdStatInit; |
assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); |
+ assert( op>=0 && op<ArraySize(statMutex) ); |
+ assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex() |
+ : sqlite3MallocMutex()) ); |
return wsdStat.nowValue[op]; |
} |
/* |
-** Add N to the value of a status record. It is assumed that the |
-** caller holds appropriate locks. |
+** Add N to the value of a status record. The caller must hold the |
+** appropriate mutex. (Locking is checked by assert()). |
+** |
+** The StatusUp() routine can accept positive or negative values for N. |
+** The value of N is added to the current status value and the high-water |
+** mark is adjusted if necessary. |
+** |
+** The StatusDown() routine lowers the current value by N. The highwater |
+** mark is unchanged. N must be non-negative for StatusDown(). |
*/ |
-void sqlite3StatusAdd(int op, int N){ |
+void sqlite3StatusUp(int op, int N){ |
wsdStatInit; |
assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); |
+ assert( op>=0 && op<ArraySize(statMutex) ); |
+ assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex() |
+ : sqlite3MallocMutex()) ); |
wsdStat.nowValue[op] += N; |
if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){ |
wsdStat.mxValue[op] = wsdStat.nowValue[op]; |
} |
} |
+void sqlite3StatusDown(int op, int N){ |
+ wsdStatInit; |
+ assert( N>=0 ); |
+ assert( op>=0 && op<ArraySize(statMutex) ); |
+ assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex() |
+ : sqlite3MallocMutex()) ); |
+ assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); |
+ wsdStat.nowValue[op] -= N; |
+} |
/* |
-** Set the value of a status to X. |
+** Adjust the highwater mark if necessary. |
+** The caller must hold the appropriate mutex. |
*/ |
-void sqlite3StatusSet(int op, int X){ |
+void sqlite3StatusHighwater(int op, int X){ |
+ sqlite3StatValueType newValue; |
wsdStatInit; |
+ assert( X>=0 ); |
+ newValue = (sqlite3StatValueType)X; |
assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); |
- wsdStat.nowValue[op] = X; |
- if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){ |
- wsdStat.mxValue[op] = wsdStat.nowValue[op]; |
+ assert( op>=0 && op<ArraySize(statMutex) ); |
+ assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex() |
+ : sqlite3MallocMutex()) ); |
+ assert( op==SQLITE_STATUS_MALLOC_SIZE |
+ || op==SQLITE_STATUS_PAGECACHE_SIZE |
+ || op==SQLITE_STATUS_SCRATCH_SIZE |
+ || op==SQLITE_STATUS_PARSER_STACK ); |
+ if( newValue>wsdStat.mxValue[op] ){ |
+ wsdStat.mxValue[op] = newValue; |
} |
} |
/* |
** Query status information. |
-** |
-** This implementation assumes that reading or writing an aligned |
-** 32-bit integer is an atomic operation. If that assumption is not true, |
-** then this routine is not threadsafe. |
*/ |
-int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){ |
+int sqlite3_status64( |
+ int op, |
+ sqlite3_int64 *pCurrent, |
+ sqlite3_int64 *pHighwater, |
+ int resetFlag |
+){ |
+ sqlite3_mutex *pMutex; |
wsdStatInit; |
if( op<0 || op>=ArraySize(wsdStat.nowValue) ){ |
return SQLITE_MISUSE_BKPT; |
} |
+#ifdef SQLITE_ENABLE_API_ARMOR |
+ if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT; |
+#endif |
+ pMutex = statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex(); |
+ sqlite3_mutex_enter(pMutex); |
*pCurrent = wsdStat.nowValue[op]; |
*pHighwater = wsdStat.mxValue[op]; |
if( resetFlag ){ |
wsdStat.mxValue[op] = wsdStat.nowValue[op]; |
} |
+ sqlite3_mutex_leave(pMutex); |
+ (void)pMutex; /* Prevent warning when SQLITE_THREADSAFE=0 */ |
return SQLITE_OK; |
} |
+int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){ |
+ sqlite3_int64 iCur, iHwtr; |
+ int rc; |
+#ifdef SQLITE_ENABLE_API_ARMOR |
+ if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT; |
+#endif |
+ rc = sqlite3_status64(op, &iCur, &iHwtr, resetFlag); |
+ if( rc==0 ){ |
+ *pCurrent = (int)iCur; |
+ *pHighwater = (int)iHwtr; |
+ } |
+ return rc; |
+} |
/* |
** Query status information for a single database connection |
@@ -105,6 +182,11 @@ int sqlite3_db_status( |
int resetFlag /* Reset high-water mark if true */ |
){ |
int rc = SQLITE_OK; /* Return code */ |
+#ifdef SQLITE_ENABLE_API_ARMOR |
+ if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){ |
+ return SQLITE_MISUSE_BKPT; |
+ } |
+#endif |
sqlite3_mutex_enter(db->mutex); |
switch( op ){ |
case SQLITE_DBSTATUS_LOOKASIDE_USED: { |
@@ -176,10 +258,10 @@ int sqlite3_db_status( |
+ pSchema->idxHash.count |
+ pSchema->fkeyHash.count |
); |
- nByte += sqlite3MallocSize(pSchema->tblHash.ht); |
- nByte += sqlite3MallocSize(pSchema->trigHash.ht); |
- nByte += sqlite3MallocSize(pSchema->idxHash.ht); |
- nByte += sqlite3MallocSize(pSchema->fkeyHash.ht); |
+ nByte += sqlite3_msize(pSchema->tblHash.ht); |
+ nByte += sqlite3_msize(pSchema->trigHash.ht); |
+ nByte += sqlite3_msize(pSchema->idxHash.ht); |
+ nByte += sqlite3_msize(pSchema->fkeyHash.ht); |
for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){ |
sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p)); |