blob: 9a12f6e8e03496cd3c4475fcce99deb7e347338e [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
30class PThreadMutex
31{
32public:
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
101 PThreadMutex()
102 {
103 int err;
104 err = ::pthread_mutex_init (&m_mutex, NULL); assert(err == 0);
105 }
106
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
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
129 pthread_mutex_t *Mutex()
130 {
131 return &m_mutex;
132 }
133
134 int Lock()
135 {
136 return ::pthread_mutex_lock (&m_mutex);
137 }
138
139 int Unlock()
140 {
141 return ::pthread_mutex_unlock (&m_mutex);
142 }
143
144protected:
145 pthread_mutex_t m_mutex;
146};
147
148#endif