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 <pthread.h> 18 #include <assert.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) PThreadMutex::Locker var(mutex, __FUNCTION__, __FILE__, __LINE__) 25 26 #else 27 #define PTHREAD_MUTEX_LOCKER(var, mutex) PThreadMutex::Locker var(mutex) 28 #endif 29 30 class PThreadMutex 31 { 32 public: 33 34 class Locker 35 { 36 public: 37 #if defined (DEBUG_PTHREAD_MUTEX_DEADLOCKS) 38 39 Locker(PThreadMutex& m, const char *function, const char *file, int line); 40 Locker(PThreadMutex* m, const char *function, const char *file, int line); 41 Locker(pthread_mutex_t *mutex, const char *function, const char *file, int line); 42 ~Locker(); 43 void Lock(); 44 void Unlock(); 45 46 #else 47 Locker(PThreadMutex& m) : 48 m_pMutex(m.Mutex()) 49 { 50 Lock(); 51 } 52 53 Locker(PThreadMutex* m) : 54 m_pMutex(m ? m->Mutex() : NULL) 55 { 56 Lock(); 57 } 58 59 Locker(pthread_mutex_t *mutex) : 60 m_pMutex(mutex) 61 { 62 Lock(); 63 } 64 65 void Lock() 66 { 67 if (m_pMutex) 68 ::pthread_mutex_lock (m_pMutex); 69 } 70 71 void Unlock() 72 { 73 if (m_pMutex) 74 ::pthread_mutex_unlock (m_pMutex); 75 } 76 77 ~Locker() 78 { 79 Unlock(); 80 } 81 82 #endif 83 84 // unlock any the current mutex and lock the new one if it is valid 85 void Reset(pthread_mutex_t *pMutex = NULL) 86 { 87 Unlock(); 88 m_pMutex = pMutex; 89 Lock(); 90 } 91 pthread_mutex_t *m_pMutex; 92 #if defined (DEBUG_PTHREAD_MUTEX_DEADLOCKS) 93 const char *m_function; 94 const char *m_file; 95 int m_line; 96 uint64_t m_lock_time; 97 #endif 98 }; 99 100 PThreadMutex()101 PThreadMutex() 102 { 103 int err; 104 err = ::pthread_mutex_init (&m_mutex, NULL); assert(err == 0); 105 } 106 PThreadMutex(int type)107 PThreadMutex(int type) 108 { 109 int err; 110 ::pthread_mutexattr_t attr; 111 err = ::pthread_mutexattr_init (&attr); assert(err == 0); 112 err = ::pthread_mutexattr_settype (&attr, type); assert(err == 0); 113 err = ::pthread_mutex_init (&m_mutex, &attr); assert(err == 0); 114 err = ::pthread_mutexattr_destroy (&attr); assert(err == 0); 115 } 116 ~PThreadMutex()117 ~PThreadMutex() 118 { 119 int err; 120 err = ::pthread_mutex_destroy (&m_mutex); 121 if (err != 0) 122 { 123 err = Unlock(); 124 if (err == 0) 125 ::pthread_mutex_destroy (&m_mutex); 126 } 127 } 128 Mutex()129 pthread_mutex_t *Mutex() 130 { 131 return &m_mutex; 132 } 133 Lock()134 int Lock() 135 { 136 return ::pthread_mutex_lock (&m_mutex); 137 } 138 Unlock()139 int Unlock() 140 { 141 return ::pthread_mutex_unlock (&m_mutex); 142 } 143 144 protected: 145 pthread_mutex_t m_mutex; 146 }; 147 148 #endif 149