xref: /openbsd-src/gnu/llvm/lldb/tools/debugserver/source/PThreadMutex.h (revision be691f3bb6417f04a68938fadbcaee2d5795e764)
1061da546Spatrick //===-- PThreadMutex.h ------------------------------------------*- C++ -*-===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick //
9061da546Spatrick //  Created by Greg Clayton on 6/16/07.
10061da546Spatrick //
11061da546Spatrick //===----------------------------------------------------------------------===//
12061da546Spatrick 
13dda28197Spatrick #ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_PTHREADMUTEX_H
14dda28197Spatrick #define LLDB_TOOLS_DEBUGSERVER_SOURCE_PTHREADMUTEX_H
15061da546Spatrick 
16*be691f3bSpatrick #include <cassert>
17*be691f3bSpatrick #include <cstdint>
18061da546Spatrick #include <pthread.h>
19061da546Spatrick 
20061da546Spatrick //#define DEBUG_PTHREAD_MUTEX_DEADLOCKS 1
21061da546Spatrick 
22061da546Spatrick #if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS)
23061da546Spatrick #define PTHREAD_MUTEX_LOCKER(var, mutex)                                       \
24061da546Spatrick   PThreadMutex::Locker var(mutex, __FUNCTION__, __FILE__, __LINE__)
25061da546Spatrick 
26061da546Spatrick #else
27061da546Spatrick #define PTHREAD_MUTEX_LOCKER(var, mutex) PThreadMutex::Locker var(mutex)
28061da546Spatrick #endif
29061da546Spatrick 
30061da546Spatrick class PThreadMutex {
31061da546Spatrick public:
32061da546Spatrick   class Locker {
33061da546Spatrick   public:
34061da546Spatrick #if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS)
35061da546Spatrick 
36061da546Spatrick     Locker(PThreadMutex &m, const char *function, const char *file, int line);
37061da546Spatrick     Locker(PThreadMutex *m, const char *function, const char *file, int line);
38061da546Spatrick     Locker(pthread_mutex_t *mutex, const char *function, const char *file,
39061da546Spatrick            int line);
40061da546Spatrick     ~Locker();
41061da546Spatrick     void Lock();
42061da546Spatrick     void Unlock();
43061da546Spatrick 
44061da546Spatrick #else
45061da546Spatrick     Locker(PThreadMutex &m) : m_pMutex(m.Mutex()) { Lock(); }
46061da546Spatrick 
47061da546Spatrick     Locker(PThreadMutex *m) : m_pMutex(m ? m->Mutex() : NULL) { Lock(); }
48061da546Spatrick 
49061da546Spatrick     Locker(pthread_mutex_t *mutex) : m_pMutex(mutex) { Lock(); }
50061da546Spatrick 
51061da546Spatrick     void Lock() {
52061da546Spatrick       if (m_pMutex)
53061da546Spatrick         ::pthread_mutex_lock(m_pMutex);
54061da546Spatrick     }
55061da546Spatrick 
56061da546Spatrick     void Unlock() {
57061da546Spatrick       if (m_pMutex)
58061da546Spatrick         ::pthread_mutex_unlock(m_pMutex);
59061da546Spatrick     }
60061da546Spatrick 
61061da546Spatrick     ~Locker() { Unlock(); }
62061da546Spatrick 
63061da546Spatrick #endif
64061da546Spatrick 
65061da546Spatrick     // unlock any the current mutex and lock the new one if it is valid
66061da546Spatrick     void Reset(pthread_mutex_t *pMutex = NULL) {
67061da546Spatrick       Unlock();
68061da546Spatrick       m_pMutex = pMutex;
69061da546Spatrick       Lock();
70061da546Spatrick     }
71061da546Spatrick     pthread_mutex_t *m_pMutex;
72061da546Spatrick #if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS)
73061da546Spatrick     const char *m_function;
74061da546Spatrick     const char *m_file;
75061da546Spatrick     int m_line;
76061da546Spatrick     uint64_t m_lock_time;
77061da546Spatrick #endif
78061da546Spatrick   };
79061da546Spatrick 
PThreadMutex()80061da546Spatrick   PThreadMutex() {
81061da546Spatrick     int err;
82061da546Spatrick     err = ::pthread_mutex_init(&m_mutex, NULL);
83061da546Spatrick     assert(err == 0);
84061da546Spatrick   }
85061da546Spatrick 
PThreadMutex(int type)86061da546Spatrick   PThreadMutex(int type) {
87061da546Spatrick     int err;
88061da546Spatrick     ::pthread_mutexattr_t attr;
89061da546Spatrick     err = ::pthread_mutexattr_init(&attr);
90061da546Spatrick     assert(err == 0);
91061da546Spatrick     err = ::pthread_mutexattr_settype(&attr, type);
92061da546Spatrick     assert(err == 0);
93061da546Spatrick     err = ::pthread_mutex_init(&m_mutex, &attr);
94061da546Spatrick     assert(err == 0);
95061da546Spatrick     err = ::pthread_mutexattr_destroy(&attr);
96061da546Spatrick     assert(err == 0);
97061da546Spatrick   }
98061da546Spatrick 
~PThreadMutex()99061da546Spatrick   ~PThreadMutex() {
100061da546Spatrick     int err;
101061da546Spatrick     err = ::pthread_mutex_destroy(&m_mutex);
102061da546Spatrick     if (err != 0) {
103061da546Spatrick       err = Unlock();
104061da546Spatrick       if (err == 0)
105061da546Spatrick         ::pthread_mutex_destroy(&m_mutex);
106061da546Spatrick     }
107061da546Spatrick   }
108061da546Spatrick 
Mutex()109061da546Spatrick   pthread_mutex_t *Mutex() { return &m_mutex; }
110061da546Spatrick 
Lock()111061da546Spatrick   int Lock() { return ::pthread_mutex_lock(&m_mutex); }
112061da546Spatrick 
Unlock()113061da546Spatrick   int Unlock() { return ::pthread_mutex_unlock(&m_mutex); }
114061da546Spatrick 
115061da546Spatrick protected:
116061da546Spatrick   pthread_mutex_t m_mutex;
117061da546Spatrick };
118061da546Spatrick 
119061da546Spatrick #endif
120