# HG changeset patch # User Matti Hamalainen # Date 1349960642 -10800 # Node ID dd9809a9342586228987e4b196c15da106719df5 # Parent bc2e8ce003d7baadc83fe2d987b0823a95c0c64a Improve mutex debugging facilities. diff -r bc2e8ce003d7 -r dd9809a93425 dmlib.c --- a/dmlib.c Thu Oct 11 16:01:14 2012 +0300 +++ b/dmlib.c Thu Oct 11 16:04:02 2012 +0300 @@ -197,3 +197,134 @@ default: return "Unknown error"; } } + + +#ifdef DM_MUTEX_DEBUG + +static DMMutexLock * dmGetMutexThreadIDLock(DMMutex *mutex) +{ + Uint32 id = SDL_ThreadID(); + int i; + for (i = 0; i < 8; i++) + { + DMMutexLock *lock = &(mutex->locks[i]); + if (lock->used && lock->id == id) + return lock; + } + return NULL; +} + +static void dmPrintMutexLocks(DMMutex *mutex, const char *state, const char *file, const int line) +{ + int i; + + fprintf(stderr, + "----------------------\n" + "%s --> %p @ %s:%d\n" + "Current thread: %d\n" + "Mutex : %p (created @ %s:%d)\n", + state, mutex, file, line, + SDL_ThreadID(), mutex, mutex->cr_file, mutex->cr_line); + + for (i = 0; i < 8; i++) + { + DMMutexLock *lock = &(mutex->locks[i]); + if (lock->used) + { + fprintf(stderr, + "Lock #%d: thread=%d, state=%d\n", + i, lock->id, lock->state); + } + } +} + +int dmDOMutexLock(DMMutex *mutex, const char *file, const int line) +{ + if (mutex != NULL) + { + dmPrintMutexLocks(mutex, "LOCKING", file, line); + + DMMutexLock *lock = dmGetMutexThreadIDLock(mutex); + if (lock != NULL) + { + int res; + if (lock->state == 0) + res = SDL_mutexP(mutex->m); + else + res = 1; + lock->state++; + fprintf(stderr, "LOCKING %p @ thread=%d done [1].\n", mutex, SDL_ThreadID()); + return res; + } + else + { + int i; + for (i = 0; i < 8; i++) + { + DMMutexLock *lock = &(mutex->locks[i]); + if (!lock->used) + { + int res; + lock->used = TRUE; + lock->id = SDL_ThreadID(); + lock->state++; + res = SDL_mutexP(mutex->m); + fprintf(stderr, "LOCKING %p @ thread=%d done [2].\n", mutex, SDL_ThreadID()); + return res; + } + } + return -2; + } + } + return -1; +} + + +int dmDOMutexUnlock(DMMutex *mutex, const char *file, const int line) +{ + if (mutex != NULL) + { + dmPrintMutexLocks(mutex, "UN-LOCKING", file, line); + + DMMutexLock *lock = dmGetMutexThreadIDLock(mutex); + if (lock != NULL) + { + int res; + lock->state--; + if (lock->state == 0) + res = SDL_mutexV(mutex->m); + else + res = lock->state; + return res; + } + else + { + return -2; + } + } + return -1; +} + + +DMMutex * dmDOCreateMutex(const char *file, const int line) +{ + DMMutex *mutex = dmMalloc0(sizeof(DMMutex)); + if (mutex == NULL) + return NULL; + mutex->cr_file = dm_strdup(file); + mutex->cr_line = line; + mutex->m = SDL_CreateMutex(); + return mutex; +} + + +void dmDestroyMutex(DMMutex *mutex) +{ + if (mutex != NULL) + { + SDL_DestroyMutex(mutex->m); + dmFree(mutex); + } +} + +#endif diff -r bc2e8ce003d7 -r dd9809a93425 dmlib.h --- a/dmlib.h Thu Oct 11 16:01:14 2012 +0300 +++ b/dmlib.h Thu Oct 11 16:04:02 2012 +0300 @@ -71,14 +71,6 @@ #define DMRES_RES_FILE "res.txt" // Resource data file -// Mutexes -#define DMMutex SDL_mutex -#define dmCreateMutex() SDL_CreateMutex() -#define dmDestroyMutex(x) SDL_DestroyMutex(x) -#define dmMutexLock(x) SDL_mutexP(x) -#define dmMutexUnlock(x) SDL_mutexV(x) - - /* Define a boolean type */ #if !defined(FALSE) && !defined(TRUE) && !defined(BOOL) @@ -381,6 +373,42 @@ char * dm_strdup_printf(const char *, ...); +/* Mutexes + */ +#ifdef DM_MUTEX_DEBUG + +typedef struct +{ + BOOL used; + Uint32 id; + int state; +} DMMutexLock; + +typedef struct +{ + char *cr_file; + int cr_line; + SDL_mutex *m; + DMMutexLock locks[8]; +} DMMutex; + +#define dmMutexLock(x) dmDOMutexLock(x, __FILE__, (int) __LINE__) +#define dmMutexUnlock(x) dmDOMutexUnlock(x, __FILE__, (int) __LINE__) +#define dmCreateMutex(x) dmDOCreateMutex(__FILE__, (int) __LINE__) + +int dmDOMutexLock(DMMutex *mutex, const char *file, const int line); +int dmDOMutexUnlock(DMMutex *mutex, const char *file, const int line); +DMMutex * dmDOCreateMutex(const char *file, const int line); +void dmDestroyMutex(DMMutex *mutex); + +#else +#define DMMutex SDL_mutex +#define dmCreateMutex() SDL_CreateMutex() +#define dmDestroyMutex(x) SDL_DestroyMutex(x) +#define dmMutexLock(x) SDL_mutexP(x) +#define dmMutexUnlock(x) SDL_mutexV(x) +#endif + /* Endianess swapping macros */ #define DM_SWAP_16_LE_BE(value) ((Uint16) ( \ diff -r bc2e8ce003d7 -r dd9809a93425 dmmutex.h --- a/dmmutex.h Thu Oct 11 16:01:14 2012 +0300 +++ b/dmmutex.h Thu Oct 11 16:04:02 2012 +0300 @@ -5,24 +5,29 @@ * (C) Copyright 2012 Tecnic Software productions (TNSP) */ -int SDL_mutexP(DMMutex *p) +Uint32 SDL_ThreadID() +{ + return 0; +} + +int SDL_mutexP(SDL_mutex *p) { (void) p; return 0; } -int SDL_mutexV(DMMutex *p) +int SDL_mutexV(SDL_mutex *p) { (void) p; return 0; } -DMMutex * SDL_CreateMutex() +SDL_mutex * SDL_CreateMutex() { return NULL; } -void SDL_DestroyMutex(DMMutex *p) +void SDL_DestroyMutex(SDL_mutex *p) { (void) p; }