diff options
author | phintuka <phintuka> | 2006-12-21 08:07:24 +0000 |
---|---|---|
committer | phintuka <phintuka> | 2006-12-21 08:07:24 +0000 |
commit | 5a0b4592eb0edb4329f8c6c78f582a46ec3ad9a6 (patch) | |
tree | c524f3081daf7e1045d70d50f00b1fa569fbceed | |
parent | e46704b696a35238a4e43648559138e7f4989e4b (diff) | |
download | xineliboutput-5a0b4592eb0edb4329f8c6c78f582a46ec3ad9a6.tar.gz xineliboutput-5a0b4592eb0edb4329f8c6c78f582a46ec3ad9a6.tar.bz2 |
Added small description and pthread_mutex_trylock wrapper
-rw-r--r-- | tools/debug_mutex.h | 75 |
1 files changed, 69 insertions, 6 deletions
diff --git a/tools/debug_mutex.h b/tools/debug_mutex.h index dc25ec7e..38bb12ce 100644 --- a/tools/debug_mutex.h +++ b/tools/debug_mutex.h @@ -4,7 +4,7 @@ * See the main source file 'xineliboutput.c' for copyright information and * how to reach the author. * - * $Id: debug_mutex.h,v 1.1 2006-12-19 17:21:50 phintuka Exp $ + * $Id: debug_mutex.h,v 1.2 2006-12-21 08:07:24 phintuka Exp $ * */ @@ -15,20 +15,44 @@ # error pthread.h must be included before debug_mutex.h #endif +/* + * Override pthread_mutex_ calls: + * + * Change type of each mutex to PTHREAD_MUTEX_ERRORCHECK_NP + * + * Store line number of last succeed pthread_mutex_lock call + * for each initialized mutex + * + * Check every pthread_mutex_ call for errors and log all errors + * + * To help detecting deadlocks and minimize logging: + * - Try locking first in pthread_mutex_lock + * - If pthread_mutex_trylock fails, log a message and retry. + * - When trylock failed, log another message when lock is acquired. + * + * + * NOTE: debugging itself is not thread-safe and may indicate wrong line numbers ! + * + */ + +#define MAX_DBG_MUTEX 64 static struct { pthread_mutex_t *lock; int line; -} dbgdata[64] = {{NULL,0}}; +} dbgdata[MAX_DBG_MUTEX+1] = {{NULL,0}}; static void dbg_setdata(pthread_mutex_t *mutex, int line) { int i; - for(i=0; i<32; i++) + for(i=0; i<MAX_DBG_MUTEX; i++) if(dbgdata[i].lock == mutex) { dbgdata[i].line = line; return; } - else if(!dbgdata[i].lock) { + + LOGMSG("********** dbg_setdata: new entry (0x%x at %d)", (unsigned long int)mutex, line); + for(i=0; i<MAX_DBG_MUTEX; i++) + if(!dbgdata[i].lock) { dbgdata[i].lock = mutex; dbgdata[i].line = line; return; @@ -40,7 +64,7 @@ static void dbg_setdata(pthread_mutex_t *mutex, int line) static int dbg_getdata(pthread_mutex_t *mutex, int line) { int i; - for(i=0; i<32; i++) + for(i=0; i<MAX_DBG_MUTEX; i++) if(dbgdata[i].lock == mutex) return dbgdata[i].line; @@ -48,10 +72,24 @@ static int dbg_getdata(pthread_mutex_t *mutex, int line) return -1; } +static void dbg_deldata(pthread_mutex_t *mutex, int line) +{ + int i; + for(i=0; i<MAX_DBG_MUTEX; i++) + if(dbgdata[i].lock == mutex) { + dbgdata[i].lock = NULL; + return; + } + + LOGMSG("********** dbg_deldata: NO ENTRY ! (%d)", line); + return; +} + static int dbg_init(pthread_mutex_t *mutex, pthread_mutexattr_t *pattr, int line) { int r; + errno = 0; if(!pattr) { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); @@ -74,11 +112,13 @@ static int dbg_free(pthread_mutex_t *mutex, int line) { int r; + errno = 0; r = pthread_mutex_destroy(mutex); if(r) LOGERR("********** dbg_free: pthread_mutex_destroy FAILED at %d ; last lock at %d", line, dbg_getdata(mutex, line)); + dbg_deldata(mutex, line); return r; } @@ -89,6 +129,7 @@ static int dbg_lock(pthread_mutex_t *mutex, int line) /*struct timespec abs_timeout;*/ /* try lock first to reduce logging */ + errno = 0; r = pthread_mutex_trylock(mutex); if(!r) { dbg_setdata(mutex,line); @@ -96,12 +137,13 @@ static int dbg_lock(pthread_mutex_t *mutex, int line) } /* try failed - we're going to wait, so log at wait start and end to detect deadlocks */ - LOGMSG("********** dbg_lock: pthread_mutex_trylock failed at %d (locked at %d)", + LOGERR("********** dbg_lock: pthread_mutex_trylock failed at %d (locked at %d)", line, dbg_getdata(mutex, line)); /* int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, const struct timespec *restrict abs_timeout); */ + errno = 0; r = pthread_mutex_lock(mutex); if(r) @@ -113,10 +155,30 @@ static int dbg_lock(pthread_mutex_t *mutex, int line) return r; } +static int dbg_trylock(pthread_mutex_t *mutex, int line) +{ + int r; + /*struct timespec abs_timeout;*/ + + /* try lock first to reduce logging */ + errno = 0; + r = pthread_mutex_trylock(mutex); + if(!r) { + dbg_setdata(mutex,line); + return r; + } + + LOGERR("********** dbg_trylock: pthread_mutex_trylock failed at %d (locked at %d)", + line, dbg_getdata(mutex, line)); + + return r; +} + static int dbg_unlock(pthread_mutex_t *mutex, int line) { int r; + errno = 0; r = pthread_mutex_unlock(mutex); if(r) @@ -129,6 +191,7 @@ static int dbg_unlock(pthread_mutex_t *mutex, int line) /* override pthread_ functions with own ones */ #define pthread_mutex_init(l,a) dbg_init(l, a, __LINE__) #define pthread_mutex_lock(l) dbg_lock(l, __LINE__) +#define pthread_mutex_trylock(l) dbg_trylock(l, __LINE__) #define pthread_mutex_unlock(l) dbg_unlock(l, __LINE__) #define pthread_mutex_destroy(l) dbg_free(l, __LINE__) |