130fdc8d8SChris Lattner //===-- PThreadMutex.h ------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 630fdc8d8SChris Lattner // 730fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 830fdc8d8SChris Lattner // 930fdc8d8SChris Lattner // Created by Greg Clayton on 6/16/07. 1030fdc8d8SChris Lattner // 1130fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 1230fdc8d8SChris Lattner 13cdc514e4SJonas Devlieghere #ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_PTHREADMUTEX_H 14cdc514e4SJonas Devlieghere #define LLDB_TOOLS_DEBUGSERVER_SOURCE_PTHREADMUTEX_H 1530fdc8d8SChris Lattner 16*76e47d48SRaphael Isemann #include <cassert> 17*76e47d48SRaphael Isemann #include <cstdint> 18b9c1b51eSKate Stone #include <pthread.h> 1930fdc8d8SChris Lattner 2030fdc8d8SChris Lattner //#define DEBUG_PTHREAD_MUTEX_DEADLOCKS 1 2130fdc8d8SChris Lattner 2230fdc8d8SChris Lattner #if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS) 23b9c1b51eSKate Stone #define PTHREAD_MUTEX_LOCKER(var, mutex) \ 24b9c1b51eSKate Stone PThreadMutex::Locker var(mutex, __FUNCTION__, __FILE__, __LINE__) 2530fdc8d8SChris Lattner 2630fdc8d8SChris Lattner #else 2730fdc8d8SChris Lattner #define PTHREAD_MUTEX_LOCKER(var, mutex) PThreadMutex::Locker var(mutex) 2830fdc8d8SChris Lattner #endif 2930fdc8d8SChris Lattner 30b9c1b51eSKate Stone class PThreadMutex { 3130fdc8d8SChris Lattner public: 32b9c1b51eSKate Stone class Locker { 3330fdc8d8SChris Lattner public: 3430fdc8d8SChris Lattner #if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS) 3530fdc8d8SChris Lattner 3630fdc8d8SChris Lattner Locker(PThreadMutex &m, const char *function, const char *file, int line); 3730fdc8d8SChris Lattner Locker(PThreadMutex *m, const char *function, const char *file, int line); 38b9c1b51eSKate Stone Locker(pthread_mutex_t *mutex, const char *function, const char *file, 39b9c1b51eSKate Stone int line); 4030fdc8d8SChris Lattner ~Locker(); 4130fdc8d8SChris Lattner void Lock(); 4230fdc8d8SChris Lattner void Unlock(); 4330fdc8d8SChris Lattner 4430fdc8d8SChris Lattner #else 45b9c1b51eSKate Stone Locker(PThreadMutex &m) : m_pMutex(m.Mutex()) { Lock(); } 4630fdc8d8SChris Lattner 47b9c1b51eSKate Stone Locker(PThreadMutex *m) : m_pMutex(m ? m->Mutex() : NULL) { Lock(); } 4830fdc8d8SChris Lattner 49b9c1b51eSKate Stone Locker(pthread_mutex_t *mutex) : m_pMutex(mutex) { Lock(); } 5030fdc8d8SChris Lattner 51b9c1b51eSKate Stone void Lock() { 5230fdc8d8SChris Lattner if (m_pMutex) 5330fdc8d8SChris Lattner ::pthread_mutex_lock(m_pMutex); 5430fdc8d8SChris Lattner } 5530fdc8d8SChris Lattner 56b9c1b51eSKate Stone void Unlock() { 5730fdc8d8SChris Lattner if (m_pMutex) 5830fdc8d8SChris Lattner ::pthread_mutex_unlock(m_pMutex); 5930fdc8d8SChris Lattner } 6030fdc8d8SChris Lattner 61b9c1b51eSKate Stone ~Locker() { Unlock(); } 6230fdc8d8SChris Lattner 6330fdc8d8SChris Lattner #endif 6430fdc8d8SChris Lattner 6530fdc8d8SChris Lattner // unlock any the current mutex and lock the new one if it is valid 66b9c1b51eSKate Stone void Reset(pthread_mutex_t *pMutex = NULL) { 6730fdc8d8SChris Lattner Unlock(); 6830fdc8d8SChris Lattner m_pMutex = pMutex; 6930fdc8d8SChris Lattner Lock(); 7030fdc8d8SChris Lattner } 7130fdc8d8SChris Lattner pthread_mutex_t *m_pMutex; 7230fdc8d8SChris Lattner #if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS) 7330fdc8d8SChris Lattner const char *m_function; 7430fdc8d8SChris Lattner const char *m_file; 7530fdc8d8SChris Lattner int m_line; 7630fdc8d8SChris Lattner uint64_t m_lock_time; 7730fdc8d8SChris Lattner #endif 7830fdc8d8SChris Lattner }; 7930fdc8d8SChris Lattner PThreadMutex()80b9c1b51eSKate Stone PThreadMutex() { 8130fdc8d8SChris Lattner int err; 82b9c1b51eSKate Stone err = ::pthread_mutex_init(&m_mutex, NULL); 83b9c1b51eSKate Stone assert(err == 0); 8430fdc8d8SChris Lattner } 8530fdc8d8SChris Lattner PThreadMutex(int type)86b9c1b51eSKate Stone PThreadMutex(int type) { 8730fdc8d8SChris Lattner int err; 8830fdc8d8SChris Lattner ::pthread_mutexattr_t attr; 89b9c1b51eSKate Stone err = ::pthread_mutexattr_init(&attr); 90b9c1b51eSKate Stone assert(err == 0); 91b9c1b51eSKate Stone err = ::pthread_mutexattr_settype(&attr, type); 92b9c1b51eSKate Stone assert(err == 0); 93b9c1b51eSKate Stone err = ::pthread_mutex_init(&m_mutex, &attr); 94b9c1b51eSKate Stone assert(err == 0); 95b9c1b51eSKate Stone err = ::pthread_mutexattr_destroy(&attr); 96b9c1b51eSKate Stone assert(err == 0); 9730fdc8d8SChris Lattner } 9830fdc8d8SChris Lattner ~PThreadMutex()99b9c1b51eSKate Stone ~PThreadMutex() { 10030fdc8d8SChris Lattner int err; 10130fdc8d8SChris Lattner err = ::pthread_mutex_destroy(&m_mutex); 102b9c1b51eSKate Stone if (err != 0) { 10330fdc8d8SChris Lattner err = Unlock(); 10430fdc8d8SChris Lattner if (err == 0) 10530fdc8d8SChris Lattner ::pthread_mutex_destroy(&m_mutex); 10630fdc8d8SChris Lattner } 10730fdc8d8SChris Lattner } 10830fdc8d8SChris Lattner Mutex()109b9c1b51eSKate Stone pthread_mutex_t *Mutex() { return &m_mutex; } 11030fdc8d8SChris Lattner Lock()111b9c1b51eSKate Stone int Lock() { return ::pthread_mutex_lock(&m_mutex); } 11230fdc8d8SChris Lattner Unlock()113b9c1b51eSKate Stone int Unlock() { return ::pthread_mutex_unlock(&m_mutex); } 11430fdc8d8SChris Lattner 11530fdc8d8SChris Lattner protected: 11630fdc8d8SChris Lattner pthread_mutex_t m_mutex; 11730fdc8d8SChris Lattner }; 11830fdc8d8SChris Lattner 11930fdc8d8SChris Lattner #endif 120