blob: c6ec293c5e59b2a788784e67bb9c0983c1709752 [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
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include <assert.h>
Kate Stoneb9c1b512016-09-06 20:57:50 +000018#include <pthread.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include <stdint.h>
20
21//#define DEBUG_PTHREAD_MUTEX_DEADLOCKS 1
22
Kate Stoneb9c1b512016-09-06 20:57:50 +000023#if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS)
24#define PTHREAD_MUTEX_LOCKER(var, mutex) \
25 PThreadMutex::Locker var(mutex, __FUNCTION__, __FILE__, __LINE__)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026
27#else
28#define PTHREAD_MUTEX_LOCKER(var, mutex) PThreadMutex::Locker var(mutex)
29#endif
30
Kate Stoneb9c1b512016-09-06 20:57:50 +000031class PThreadMutex {
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000033 class Locker {
34 public:
35#if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036
Kate Stoneb9c1b512016-09-06 20:57:50 +000037 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();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044
45#else
Kate Stoneb9c1b512016-09-06 20:57:50 +000046 Locker(PThreadMutex &m) : m_pMutex(m.Mutex()) { Lock(); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047
Kate Stoneb9c1b512016-09-06 20:57:50 +000048 Locker(PThreadMutex *m) : m_pMutex(m ? m->Mutex() : NULL) { Lock(); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049
Kate Stoneb9c1b512016-09-06 20:57:50 +000050 Locker(pthread_mutex_t *mutex) : m_pMutex(mutex) { Lock(); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051
Kate Stoneb9c1b512016-09-06 20:57:50 +000052 void Lock() {
53 if (m_pMutex)
54 ::pthread_mutex_lock(m_pMutex);
55 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056
Kate Stoneb9c1b512016-09-06 20:57:50 +000057 void Unlock() {
58 if (m_pMutex)
59 ::pthread_mutex_unlock(m_pMutex);
60 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000061
Kate Stoneb9c1b512016-09-06 20:57:50 +000062 ~Locker() { Unlock(); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063
64#endif
65
Kate Stoneb9c1b512016-09-06 20:57:50 +000066 // 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;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000078#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 };
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080
Kate Stoneb9c1b512016-09-06 20:57:50 +000081 PThreadMutex() {
82 int err;
83 err = ::pthread_mutex_init(&m_mutex, NULL);
84 assert(err == 0);
85 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000086
Kate Stoneb9c1b512016-09-06 20:57:50 +000087 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);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000107 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000108 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000109
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110 pthread_mutex_t *Mutex() { return &m_mutex; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000111
Kate Stoneb9c1b512016-09-06 20:57:50 +0000112 int Lock() { return ::pthread_mutex_lock(&m_mutex); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000113
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114 int Unlock() { return ::pthread_mutex_unlock(&m_mutex); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000115
116protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117 pthread_mutex_t m_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000118};
119
120#endif