diff --git a/stepmania/src/RageThreads.cpp b/stepmania/src/RageThreads.cpp index c98e3760a9..bc8211f195 100644 --- a/stepmania/src/RageThreads.cpp +++ b/stepmania/src/RageThreads.cpp @@ -13,6 +13,9 @@ #include "stdafx.h" #include "RageThreads.h" +#include "RageTimer.h" +#include "RageLog.h" +#include "RageUtil.h" RageMutex::RageMutex() { @@ -69,6 +72,27 @@ void RageMutex::Unlock() SDL_UnlockMutex(mut); } +LockMutex::LockMutex(RageMutex &mut, const char *file_, int line_): + mutex(mut), + file(file_), + line(line_), + locked_at(RageTimer::GetTimeSinceStart()) +{ + mutex.Lock(); +} + +LockMutex::~LockMutex() +{ + mutex.Unlock(); + + if(file) + { + float dur = RageTimer::GetTimeSinceStart() - locked_at; + if(dur > 0.015) + LOG->Trace(ssprintf("Lock at %s:%i took %f", file, line, dur)); + } +} + /* ----------------------------------------------------------------------------- File: RageThreads diff --git a/stepmania/src/RageThreads.h b/stepmania/src/RageThreads.h index 3f3fd42232..eb14785c41 100644 --- a/stepmania/src/RageThreads.h +++ b/stepmania/src/RageThreads.h @@ -27,10 +27,31 @@ class LockMutex { RageMutex &mutex; + const char *file; + int line; + float locked_at; + public: - LockMutex(RageMutex &mut): mutex(mut) { mutex.Lock(); } - ~LockMutex() { mutex.Unlock(); } - LockMutex(LockMutex &cpy): mutex(cpy.mutex) { mutex.Lock(); } + LockMutex(RageMutex &mut, const char *file, int line); + LockMutex(RageMutex &mut): mutex(mut), file(NULL), line(-1), locked_at(0) { mutex.Lock(); } + ~LockMutex(); + LockMutex(LockMutex &cpy): mutex(cpy.mutex), file(cpy.file), line(cpy.line), locked_at(cpy.locked_at) { mutex.Lock(); } }; +/* Double-abstracting __LINE__ lets us append it to other text, to generate + * locally unique variable names. (Otherwise we get "LocalLock__LINE__".) I'm + * not sure why this works, but it does, in both VC and GCC. */ + +#ifdef DEBUG +/* Use the debug version, which logs if something holds a lock for a long time. + * __FUNCTION__ is nonstandard, but both GCC and VC support it; VC doesn't + * support the standard, __func__. */ +#define LockMutL2(m, l) LockMutex LocalLock ## l (m, __FUNCTION__, __LINE__) +#else +#define LockMutL2(m, l) LockMutex LocalLock ## l (m) +#endif + +#define LockMutL(m, l) LockMutL2(m, l) +#define LockMut(m) LockMutL(m, __LINE__) + #endif