From 7134f4b13a4c4b8b68dd16aec4dfa56ba28ef7d7 Mon Sep 17 00:00:00 2001 From: phintuka Date: Tue, 19 Dec 2006 17:21:50 +0000 Subject: Initial import --- tools/debug_mutex.h | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 tools/debug_mutex.h diff --git a/tools/debug_mutex.h b/tools/debug_mutex.h new file mode 100644 index 00000000..dc25ec7e --- /dev/null +++ b/tools/debug_mutex.h @@ -0,0 +1,137 @@ +/* + * debug_mutex.h: debugging wrappers for pthread_mutex_ functions + * + * 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 $ + * + */ + +#ifndef DEBUG_MUTEX_H +#define DEBUG_MUTEX_H + +#ifndef _PTHREAD_H +# error pthread.h must be included before debug_mutex.h +#endif + +static struct { + pthread_mutex_t *lock; + int line; +} dbgdata[64] = {{NULL,0}}; + +static void dbg_setdata(pthread_mutex_t *mutex, int line) +{ + int i; + for(i=0; i<32; i++) + if(dbgdata[i].lock == mutex) { + dbgdata[i].line = line; + return; + } + else if(!dbgdata[i].lock) { + dbgdata[i].lock = mutex; + dbgdata[i].line = line; + return; + } + + LOGMSG("********** dbg_setdata: table full !"); +} + +static int dbg_getdata(pthread_mutex_t *mutex, int line) +{ + int i; + for(i=0; i<32; i++) + if(dbgdata[i].lock == mutex) + return dbgdata[i].line; + + LOGMSG("********** dbg_getdata: NO ENTRY ! (%d)", line); + return -1; +} + +static int dbg_init(pthread_mutex_t *mutex, pthread_mutexattr_t *pattr, int line) +{ + int r; + + if(!pattr) { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP); + r = pthread_mutex_init(mutex, &attr); + } else { + LOGMSG("********** dbg_init: mutex attribute already given !"); + r = pthread_mutex_init(mutex, pattr); + } + + if(r) + LOGERR("********** dbg_init: pthread_mutex_init FAILED at %d", line); + + dbg_setdata(mutex, line); + + return r; +} + +static int dbg_free(pthread_mutex_t *mutex, int line) +{ + int r; + + 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)); + + return r; +} + +static int dbg_lock(pthread_mutex_t *mutex, int line) +{ + int r; + /*struct timespec abs_timeout;*/ + + /* try lock first to reduce logging */ + r = pthread_mutex_trylock(mutex); + if(!r) { + dbg_setdata(mutex,line); + return r; + } + + /* 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)", + line, dbg_getdata(mutex, line)); + + /* int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, + const struct timespec *restrict abs_timeout); */ + + r = pthread_mutex_lock(mutex); + + if(r) + LOGERR("********** dbg_lock: pthread_mutex_lock FAILED at %d", line); + + dbg_setdata(mutex, line); + LOGMSG("********** dbg_lock: pthread_mutex_lock done at %d", line); + + return r; +} + +static int dbg_unlock(pthread_mutex_t *mutex, int line) +{ + int r; + + r = pthread_mutex_unlock(mutex); + + if(r) + LOGERR("********** dbg_unlock: pthread_mutex_unlock FAILED at %d (last locket at %d)", + line, dbg_getdata(mutex, line)); + + return r; +} + +/* 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_unlock(l) dbg_unlock(l, __LINE__) +#define pthread_mutex_destroy(l) dbg_free(l, __LINE__) + +#else +# error debug_mutex.h included twice +#endif /* DEBUG_MUTEX_H */ -- cgit v1.2.3