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