1 //===-- PThreadMutex.h ------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Created by Greg Clayton on 6/16/07. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef __PThreadMutex_h__ 15 #define __PThreadMutex_h__ 16 17 #include <assert.h> 18 #include <pthread.h> 19 #include <stdint.h> 20 21 //#define DEBUG_PTHREAD_MUTEX_DEADLOCKS 1 22 23 #if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS) 24 #define PTHREAD_MUTEX_LOCKER(var, mutex) \ 25 PThreadMutex::Locker var(mutex, __FUNCTION__, __FILE__, __LINE__) 26 27 #else 28 #define PTHREAD_MUTEX_LOCKER(var, mutex) PThreadMutex::Locker var(mutex) 29 #endif 30 31 class PThreadMutex { 32 public: 33 class Locker { 34 public: 35 #if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS) 36 37 Locker(PThreadMutex &m, const char *function, const char *file, int line); 38 Locker(PThreadMutex *m, const char *function, const char *file, int line); 39 Locker(pthread_mutex_t *mutex, const char *function, const char *file, 40 int line); 41 ~Locker(); 42 void Lock(); 43 void Unlock(); 44 45 #else 46 Locker(PThreadMutex &m) : m_pMutex(m.Mutex()) { Lock(); } 47 48 Locker(PThreadMutex *m) : m_pMutex(m ? m->Mutex() : NULL) { Lock(); } 49 50 Locker(pthread_mutex_t *mutex) : m_pMutex(mutex) { Lock(); } 51 52 void Lock() { 53 if (m_pMutex) 54 ::pthread_mutex_lock(m_pMutex); 55 } 56 57 void Unlock() { 58 if (m_pMutex) 59 ::pthread_mutex_unlock(m_pMutex); 60 } 61 62 ~Locker() { Unlock(); } 63 64 #endif 65 66 // unlock any the current mutex and lock the new one if it is valid 67 void Reset(pthread_mutex_t *pMutex = NULL) { 68 Unlock(); 69 m_pMutex = pMutex; 70 Lock(); 71 } 72 pthread_mutex_t *m_pMutex; 73 #if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS) 74 const char *m_function; 75 const char *m_file; 76 int m_line; 77 uint64_t m_lock_time; 78 #endif 79 }; 80 81 PThreadMutex() { 82 int err; 83 err = ::pthread_mutex_init(&m_mutex, NULL); 84 assert(err == 0); 85 } 86 87 PThreadMutex(int type) { 88 int err; 89 ::pthread_mutexattr_t attr; 90 err = ::pthread_mutexattr_init(&attr); 91 assert(err == 0); 92 err = ::pthread_mutexattr_settype(&attr, type); 93 assert(err == 0); 94 err = ::pthread_mutex_init(&m_mutex, &attr); 95 assert(err == 0); 96 err = ::pthread_mutexattr_destroy(&attr); 97 assert(err == 0); 98 } 99 100 ~PThreadMutex() { 101 int err; 102 err = ::pthread_mutex_destroy(&m_mutex); 103 if (err != 0) { 104 err = Unlock(); 105 if (err == 0) 106 ::pthread_mutex_destroy(&m_mutex); 107 } 108 } 109 110 pthread_mutex_t *Mutex() { return &m_mutex; } 111 112 int Lock() { return ::pthread_mutex_lock(&m_mutex); } 113 114 int Unlock() { return ::pthread_mutex_unlock(&m_mutex); } 115 116 protected: 117 pthread_mutex_t m_mutex; 118 }; 119 120 #endif 121