123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- #ifndef AUTOLOCKH
- #define AUTOLOCKH
- #ifdef _WIN32
- #pragma warning (disable:4786)
- #include <windows.h>
- #elif defined(__linux__) || defined(__APPLE__)
- #include <pthread.h>
- #else
- #error port me!!
- #endif
-
- #ifdef NULLSOFT_LOCK_OUTPUT_STATS
- #include <string> // we save each function name as a string
- #include <deque> // we make a list of the recursive function stack for each thread
- #include <map> // and map
- #include <iostream> // we output to std::cerr
- #include <windows.h>
- #define MANUALLOCKNAME(x) x
- #define LOCKNAME(x) ,x
- #define GUARDNAME(x) (x)
- namespace Nullsoft
- {
- namespace Utility
- {
-
- class LockGuard
- {
- public:
- inline LockGuard(const char *name = "Unnamed Guard")
- {
- lockName = name;
- InitializeCriticalSection(&cerr_cs);
- InitializeCriticalSection(&map_cs);
- InitializeCriticalSection(&m_cs);
- }
- inline ~LockGuard()
- {
- DeleteCriticalSection(&cerr_cs);
- DeleteCriticalSection(&map_cs);
- DeleteCriticalSection(&m_cs);
- }
- inline void Lock()
- {
- EnterCriticalSection(&m_cs);
- }
- inline void Unlock()
- {
- LeaveCriticalSection(&m_cs);
- }
- int ThreadCount()
- {
- EnterCriticalSection(&map_cs);
- int count = 0;
- for (ThreadMap::iterator itr = threads.begin(); itr != threads.end(); itr++)
- {
- if (!itr->second.empty())
- count++;
- }
- LeaveCriticalSection(&map_cs);
- return count;
- }
- void Display()
- {
- EnterCriticalSection(&map_cs);
- EnterCriticalSection(&cerr_cs);
- if (ThreadCount() > 1 && owner)
- {
- std::cerr << "Guard: " << lockName << std::endl;
- for (ThreadMap::iterator itr = threads.begin(); itr != threads.end(); itr++)
- {
- if (itr->second.empty())
- continue;
- std::cerr << " Thread ID: " << std::hex << itr->first << std::dec;
- if (owner == itr->first)
- std::cerr << " [holding the mutex] *****";
- else
- std::cerr << " [blocked]";
- std::cerr << std::endl;
- for (FunctionStack::iterator fitr = itr->second.begin(); fitr != itr->second.end(); fitr++)
- {
- std::cerr << " " << *fitr << "();" << std::endl;
- }
- }
- }
- LeaveCriticalSection(&cerr_cs);
- LeaveCriticalSection(&map_cs);
- }
- void In(DWORD thread, const char *functionName)
- {
- EnterCriticalSection(&map_cs);
- threads[thread].push_back(functionName);
- LeaveCriticalSection(&map_cs);
- }
- void Out(DWORD thread)
- {
- EnterCriticalSection(&map_cs);
- threads[thread].pop_back();
- LeaveCriticalSection(&map_cs);
- }
- std::string lockName;
- CRITICAL_SECTION cerr_cs, map_cs;
- typedef std::deque<std::string> FunctionStack;
- typedef std::map<DWORD, FunctionStack> ThreadMap;
- ThreadMap threads;
- DWORD owner;
- private:
- CRITICAL_SECTION m_cs;
- };
-
- class AutoLock
- {
- public:
-
- inline AutoLock(LockGuard &_guard, const char *functionName = "function name not passed") : guard(&_guard)
- {
- ManualLock(functionName);
- }
- inline void ManualLock(char *functionName = "manual lock")
- {
- thisThread = GetCurrentThreadId();
- guard->In(thisThread, functionName);
- guard->Display();
- guard->Lock();
- guard->owner = thisThread;
- guard->Display();
- }
- inline void ManualUnlock()
- {
- guard->Display();
- guard->Unlock();
- InterlockedCompareExchange((LONG volatile *)&guard->owner, 0, (LONG)thisThread);
-
- guard->Out(thisThread);
- guard->Display();
- }
- inline ~AutoLock()
- {
- ManualUnlock();
- }
- LockGuard *guard;
- DWORD thisThread;
- };
- }
- }
- #else
- #define MANUALLOCKNAME(x)
- #define LOCKNAME(x)
- #define GUARDNAME(x)
- namespace nu
- {
-
- class LockGuard
- {
- public:
- inline LockGuard(const char *guardName = "")
- {
- #ifdef _WIN32
- InitializeCriticalSection(&m_cs);
- #elif defined(__linux__)
- pthread_mutexattr_t mtxattr;
- pthread_mutexattr_init(&mtxattr);
- pthread_mutexattr_settype(&mtxattr, PTHREAD_MUTEX_RECURSIVE_NP );
- pthread_mutex_init(&mtx, &mtxattr);
- pthread_mutexattr_destroy(&mtxattr);
- #elif defined(__APPLE__)
- pthread_mutexattr_t mtxattr;
- pthread_mutexattr_init(&mtxattr);
- pthread_mutexattr_settype(&mtxattr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&mtx, &mtxattr);
- pthread_mutexattr_destroy(&mtxattr);
- #else
- #error port me
- #endif
- }
- inline ~LockGuard()
- {
- #ifdef _WIN32
- DeleteCriticalSection(&m_cs);
- #elif defined(__linux__) || defined(__APPLE__)
- pthread_mutex_destroy(&mtx);
- #else
- #error port me!
- #endif
- }
- inline void Lock()
- {
- #ifdef _WIN32
- EnterCriticalSection(&m_cs);
- #elif defined(__linux__) || defined(__APPLE__)
- pthread_mutex_lock(&mtx);
- #else
- #error por tme!
- #endif
- }
- inline void Unlock()
- {
- #ifdef _WIN32
- LeaveCriticalSection(&m_cs);
- #elif defined(__linux__) || defined(__APPLE__)
- pthread_mutex_unlock(&mtx);
- #else
- #error port me!
- #endif
- }
- private:
- #ifdef _WIN32
- CRITICAL_SECTION m_cs;
- #elif defined(__linux__) || defined(__APPLE__)
- pthread_mutex_t mtx;
- #else
- #error port me!
- #endif
- };
-
- class AutoLock
- {
- public:
- inline AutoLock(LockGuard &_guard) : guard(&_guard)
- {
- guard->Lock();
- }
-
- inline AutoLock(LockGuard *_guard) : guard(_guard)
- {
- guard->Lock();
- }
- inline void ManualLock()
- {
- guard->Lock();
- }
- inline void ManualUnlock()
- {
- guard->Unlock();
- }
- inline ~AutoLock()
- {
- guard->Unlock();
- }
- LockGuard *guard;
- };
-
- template <class LockGuard_t>
- class AutoLockT
- {
- public:
- inline AutoLockT(LockGuard_t &_guard) : guard(&_guard)
- {
- guard->Lock();
- }
-
- inline AutoLockT(LockGuard_t *_guard) : guard(_guard)
- {
- guard->Lock();
- }
- inline void ManualLock()
- {
- guard->Lock();
- }
- inline void ManualUnlock()
- {
- guard->Unlock();
- }
- inline ~AutoLockT()
- {
- guard->Unlock();
- }
- LockGuard_t *guard;
- };
- }
- #endif
- #endif
|