Compare commits

...

5 Commits

Author SHA1 Message Date
mistachkin 8f6788b81a Make SQLITE_GET_MUTEX_TIME a proper noop on non-Win32/non-POSIX.
FossilOrigin-Name: 4ca2b2f8f593b6995d929cf7e64b7b1459ac3c5c
2017-02-15 01:02:10 +00:00
mistachkin bac9c36496 Another compilation fix for POSIX.
FossilOrigin-Name: 82ef47ea88d59e0e97492d61c16a3a36f87e1efd
2017-02-15 00:52:50 +00:00
mistachkin 00fa6d81da Make fine time granularity work on POSIX.
FossilOrigin-Name: 79057716d9ab9e05acdc1f204940ddd540a8f2ef
2017-02-15 00:45:53 +00:00
mistachkin 3161bc5cb6 Compilation fix for POSIX.
FossilOrigin-Name: 9964ad245f66cd04cb41338180b65923ef093094
2017-02-15 00:02:02 +00:00
mistachkin f284988320 Experimental enhancements to mutex debugging.
FossilOrigin-Name: 804817549cfecbe5e1c4cea605d54cb4164f9bb6
2017-02-14 23:58:30 +00:00
7 changed files with 180 additions and 12 deletions
+11 -11
View File
@@ -1,5 +1,5 @@
C Clarification\sof\sthe\shelp\stext\sfor\sthe\scommand-line\sshell.
D 2017-02-14T21:47:46.389
C Make\sSQLITE_GET_MUTEX_TIME\sa\sproper\snoop\son\snon-Win32/non-POSIX.
D 2017-02-15T01:02:10.133
F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99
@@ -368,11 +368,11 @@ F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
F src/memjournal.c 95752936c11dc6995672d1dd783cd633eea0cc95
F src/msvc.h 4942752b6a253116baaa8de75256c51a459a5e81
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
F src/mutex.c 3e57053d0ae76dc802b102567fe2f0def1131db0
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23
F src/mutex_w32.c 3631e57d056062807ae2c92b79f3d1c05f04ecfe
F src/mutex_noop.c 6a0ac0bd696bbc600ed94302ae10a4337791b9d0
F src/mutex_unix.c 68ced9b5a25dda67346b45b0e0ee303e98f2f98f
F src/mutex_w32.c 285c1f2c3eb68b7c604faadc9a8aee09c2d78a5f
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
F src/os.c add02933b1dce7a39a005b00a2f5364b763e9a24
F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343
@@ -399,7 +399,7 @@ F src/shell.c a661e7ccd202b16cb5321999354699e5ee018fb2
F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
F src/sqliteInt.h c3f878dcbe947938f9e0984644f1902dd9051094
F src/sqliteInt.h 96b7be01cd64666a507e23bcbd42c0692fba7eae
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 54836270c9c0bfa5910f7ad74ec238b9d7ddee5f
R 81ac83b9aa3d80dbb34372d0527e01bd
U drh
Z 42f594c3c0159a4f4af8ef6e693c76a8
P 82ef47ea88d59e0e97492d61c16a3a36f87e1efd
R 6c1637446e808b4781ed15a8d4f69473
U mistachkin
Z 91f1902ac42deaf677e519dfc6e14578
+1 -1
View File
@@ -1 +1 @@
ca4f1e4962df64ae756c286f3795af7d6f692cdd
4ca2b2f8f593b6995d929cf7e64b7b1459ac3c5c
+47
View File
@@ -14,6 +14,12 @@
** This file contains code that is common across all mutex implementations.
*/
#include "sqliteInt.h"
#if SQLITE_OS_UNIX
# include <sys/time.h>
# include <pthread.h>
#elif SQLITE_OS_WIN
# include "os_win.h"
#endif
#if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT)
/*
@@ -83,6 +89,47 @@ int sqlite3MutexEnd(void){
return rc;
}
#if SQLITE_MUTEX_ALERT_MILLISECONDS>0
/* Return a time value for use by the mutex subsystem. */
i64 sqlite3MutexTimeOfDay(void){
#ifdef SQLITE_GET_MUTEX_TIME
SQLITE_GET_MUTEX_TIME;
#else
return 0;
#endif
}
/*
** Calculates the elapsed time, in milliseconds, that a particular mutex
** was held and issues a warning, via the sqlite3_log() interface, if it
** was held for "too long".
*/
void sqlite3MutexTimeAlert(
sqlite3_mutex *p,
i64 entered
){
i64 exited = sqlite3MutexTimeOfDay();
i64 elapsed;
assert( p!=0 );
assert( exited>=entered );
elapsed = exited - entered;
if( elapsed>SQLITE_MUTEX_ALERT_MILLISECONDS ){
void *tid = 0;
int mid = -1;
#ifdef SQLITE_GET_THREAD_ID
tid = SQLITE_GET_THREAD_ID();
#endif
#ifdef SQLITE_GET_MUTEX_ID
mid = SQLITE_GET_MUTEX_ID(p);
#endif
sqlite3_log(SQLITE_NOTICE,
"thread %p delayed %lldms for mutex %p (%d)",
tid, elapsed, p, mid
);
}
}
#endif
/*
** Retrieve a pointer to a static mutex or allocate a new dynamic one.
*/
+12
View File
@@ -80,6 +80,9 @@ sqlite3_mutex_methods const *sqlite3NoopMutex(void){
typedef struct sqlite3_debug_mutex {
int id; /* The mutex type */
int cnt; /* Number of entries without a matching leave */
#if SQLITE_MUTEX_ALERT_MILLISECONDS>0
i64 entered; /* Time that mutex was entered */
#endif
} sqlite3_debug_mutex;
/*
@@ -164,11 +167,17 @@ static void debugMutexEnter(sqlite3_mutex *pX){
sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
p->cnt++;
#if SQLITE_MUTEX_ALERT_MILLISECONDS>0
p->entered = sqlite3MutexTimeOfDay();
#endif
}
static int debugMutexTry(sqlite3_mutex *pX){
sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
p->cnt++;
#if SQLITE_MUTEX_ALERT_MILLISECONDS>0
p->entered = sqlite3MutexTimeOfDay();
#endif
return SQLITE_OK;
}
@@ -181,6 +190,9 @@ static int debugMutexTry(sqlite3_mutex *pX){
static void debugMutexLeave(sqlite3_mutex *pX){
sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
assert( debugMutexHeld(pX) );
#if SQLITE_MUTEX_ALERT_MILLISECONDS>0
sqlite3MutexTimeAlert((sqlite3_mutex*)p, p->entered);
#endif
p->cnt--;
assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
}
+21
View File
@@ -43,6 +43,9 @@ struct sqlite3_mutex {
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
int id; /* Mutex type */
#endif
#if SQLITE_MUTEX_ALERT_MILLISECONDS>0
i64 entered; /* Time that mutex was entered */
#endif
#if SQLITE_MUTEX_NREF
volatile int nRef; /* Number of entrances */
volatile pthread_t owner; /* Thread that is within this mutex */
@@ -261,6 +264,9 @@ static void pthreadMutexEnter(sqlite3_mutex *p){
p->nRef++;
}else{
pthread_mutex_lock(&p->mutex);
#if SQLITE_MUTEX_ALERT_MILLISECONDS>0
p->entered = sqlite3MutexTimeOfDay();
#endif
assert( p->nRef==0 );
p->owner = self;
p->nRef = 1;
@@ -270,6 +276,9 @@ static void pthreadMutexEnter(sqlite3_mutex *p){
/* Use the built-in recursive mutexes if they are available.
*/
pthread_mutex_lock(&p->mutex);
#if SQLITE_MUTEX_ALERT_MILLISECONDS>0
p->entered = sqlite3MutexTimeOfDay();
#endif
#if SQLITE_MUTEX_NREF
assert( p->nRef>0 || p->owner==0 );
p->owner = pthread_self();
@@ -304,6 +313,9 @@ static int pthreadMutexTry(sqlite3_mutex *p){
p->nRef++;
rc = SQLITE_OK;
}else if( pthread_mutex_trylock(&p->mutex)==0 ){
#if SQLITE_MUTEX_ALERT_MILLISECONDS>0
p->entered = sqlite3MutexTimeOfDay();
#endif
assert( p->nRef==0 );
p->owner = self;
p->nRef = 1;
@@ -316,6 +328,9 @@ static int pthreadMutexTry(sqlite3_mutex *p){
/* Use the built-in recursive mutexes if they are available.
*/
if( pthread_mutex_trylock(&p->mutex)==0 ){
#if SQLITE_MUTEX_ALERT_MILLISECONDS>0
p->entered = sqlite3MutexTimeOfDay();
#endif
#if SQLITE_MUTEX_NREF
p->owner = pthread_self();
p->nRef++;
@@ -350,9 +365,15 @@ static void pthreadMutexLeave(sqlite3_mutex *p){
#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
if( p->nRef==0 ){
#if SQLITE_MUTEX_ALERT_MILLISECONDS>0
sqlite3MutexTimeAlert(p, p->entered);
#endif
pthread_mutex_unlock(&p->mutex);
}
#else
#if SQLITE_MUTEX_ALERT_MILLISECONDS>0
sqlite3MutexTimeAlert(p, p->entered);
#endif
pthread_mutex_unlock(&p->mutex);
#endif
+12
View File
@@ -37,6 +37,9 @@
struct sqlite3_mutex {
CRITICAL_SECTION mutex; /* Mutex controlling the lock */
int id; /* Mutex type */
#if SQLITE_MUTEX_ALERT_MILLISECONDS>0
i64 entered; /* Time that mutex was entered */
#endif
#ifdef SQLITE_DEBUG
volatile int nRef; /* Number of enterances */
volatile DWORD owner; /* Thread holding this mutex */
@@ -293,6 +296,9 @@ static void winMutexEnter(sqlite3_mutex *p){
#endif
assert( winMutex_isInit==1 );
EnterCriticalSection(&p->mutex);
#if SQLITE_MUTEX_ALERT_MILLISECONDS>0
p->entered = sqlite3MutexTimeOfDay();
#endif
#ifdef SQLITE_DEBUG
assert( p->nRef>0 || p->owner==0 );
p->owner = tid;
@@ -330,6 +336,9 @@ static int winMutexTry(sqlite3_mutex *p){
}
assert( winMutex_isNt==0 || winMutex_isNt==1 );
if( winMutex_isNt && TryEnterCriticalSection(&p->mutex) ){
#if SQLITE_MUTEX_ALERT_MILLISECONDS>0
p->entered = sqlite3MutexTimeOfDay();
#endif
#ifdef SQLITE_DEBUG
p->owner = tid;
p->nRef++;
@@ -367,6 +376,9 @@ static void winMutexLeave(sqlite3_mutex *p){
assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
#endif
assert( winMutex_isInit==1 );
#if SQLITE_MUTEX_ALERT_MILLISECONDS>0
sqlite3MutexTimeAlert(p, p->entered);
#endif
LeaveCriticalSection(&p->mutex);
#ifdef SQLITE_DEBUG
if( p->trace ){
+76
View File
@@ -3526,6 +3526,82 @@ const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
# define sqlite3MemoryBarrier()
#endif
/*
** When SQLITE_MUTEX_ALERT_MILLISECONDS is greater than zero, extra code
** will be included to issue warnings via the sqlite3_log() interface if
** a mutex is held for longer than the number of milliseconds specified
** by SQLITE_MUTEX_ALERT_MILLISECONDS.
*/
#ifndef SQLITE_MUTEX_ALERT_MILLISECONDS
# define SQLITE_MUTEX_ALERT_MILLISECONDS (0)
#endif
#if !defined(SQLITE_MUTEX_OMIT) && SQLITE_MUTEX_ALERT_MILLISECONDS>0
i64 sqlite3MutexTimeOfDay(void);
void sqlite3MutexTimeAlert(sqlite3_mutex *, i64);
/*
** This macro contains code that returns a 64-bit integer time value,
** in milliseconds, or zero if that information is not available.
*/
# ifndef SQLITE_GET_MUTEX_TIME
# if SQLITE_OS_UNIX
# define SQLITE_GET_MUTEX_TIME { \
struct timeval sNow; (void)gettimeofday(&sNow, 0); \
return 1000*(i64)sNow.tv_sec + sNow.tv_usec/1000; \
}
# elif SQLITE_OS_WIN
# define SQLITE_GET_MUTEX_TIME { \
return (i64)GetTickCount(); \
}
# else
# define SQLITE_GET_MUTEX_TIME { \
return 0; \
}
# endif
# endif
/*
** This macro returns the integer type for the specified mutex or
** negative one if that information is not available.
*/
# ifndef SQLITE_GET_MUTEX_ID
# if SQLITE_OS_UNIX
# if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
# define SQLITE_GET_MUTEX_ID(p) \
*((int*)(((unsigned char*)(p))+sizeof(pthread_mutex_t)))
# else
# define SQLITE_GET_MUTEX_ID(p) (-1)
# endif
# elif SQLITE_OS_WIN
# define SQLITE_GET_MUTEX_ID(p) \
*((int*)(((unsigned char*)(p))+sizeof(CRITICAL_SECTION)))
# else
# define SQLITE_GET_MUTEX_ID(p) (-1)
# endif
# endif
/*
** This macro returns the integer identifier for the current thread
** or zero if that information is not available.
*/
# ifndef SQLITE_GET_THREAD_ID
# if SQLITE_OS_UNIX
# define SQLITE_GET_THREAD_ID() ((void *)pthread_self())
# elif SQLITE_OS_WIN
# define SQLITE_GET_THREAD_ID() ((void *)GetCurrentThreadId())
# else
# define SQLITE_GET_THREAD_ID() ((void *)0)
# endif
# endif
#else
# define sqlite3MutexTimeOfDay() (0)
# define sqlite3MutexTimeAlert(X,Y)
# define SQLITE_GET_MUTEX_TIME
# define SQLITE_GET_MUTEX_ID(p) (-1)
# define SQLITE_GET_THREAD_ID() ((void *)0)
#endif
sqlite3_int64 sqlite3StatusValue(int);
void sqlite3StatusUp(int, int);
void sqlite3StatusDown(int, int);