diff options
Diffstat (limited to 'tools/debugserver/source/PThreadMutex.h')
-rw-r--r-- | tools/debugserver/source/PThreadMutex.h | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/tools/debugserver/source/PThreadMutex.h b/tools/debugserver/source/PThreadMutex.h new file mode 100644 index 0000000000000..9a12f6e8e0349 --- /dev/null +++ b/tools/debugserver/source/PThreadMutex.h @@ -0,0 +1,148 @@ +//===-- PThreadMutex.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Created by Greg Clayton on 6/16/07. +// +//===----------------------------------------------------------------------===// + +#ifndef __PThreadMutex_h__ +#define __PThreadMutex_h__ + +#include <pthread.h> +#include <assert.h> +#include <stdint.h> + +//#define DEBUG_PTHREAD_MUTEX_DEADLOCKS 1 + +#if defined (DEBUG_PTHREAD_MUTEX_DEADLOCKS) +#define PTHREAD_MUTEX_LOCKER(var, mutex) PThreadMutex::Locker var(mutex, __FUNCTION__, __FILE__, __LINE__) + +#else +#define PTHREAD_MUTEX_LOCKER(var, mutex) PThreadMutex::Locker var(mutex) +#endif + +class PThreadMutex +{ +public: + + class Locker + { + public: +#if defined (DEBUG_PTHREAD_MUTEX_DEADLOCKS) + + Locker(PThreadMutex& m, const char *function, const char *file, int line); + Locker(PThreadMutex* m, const char *function, const char *file, int line); + Locker(pthread_mutex_t *mutex, const char *function, const char *file, int line); + ~Locker(); + void Lock(); + void Unlock(); + +#else + Locker(PThreadMutex& m) : + m_pMutex(m.Mutex()) + { + Lock(); + } + + Locker(PThreadMutex* m) : + m_pMutex(m ? m->Mutex() : NULL) + { + Lock(); + } + + Locker(pthread_mutex_t *mutex) : + m_pMutex(mutex) + { + Lock(); + } + + void Lock() + { + if (m_pMutex) + ::pthread_mutex_lock (m_pMutex); + } + + void Unlock() + { + if (m_pMutex) + ::pthread_mutex_unlock (m_pMutex); + } + + ~Locker() + { + Unlock(); + } + +#endif + + // unlock any the current mutex and lock the new one if it is valid + void Reset(pthread_mutex_t *pMutex = NULL) + { + Unlock(); + m_pMutex = pMutex; + Lock(); + } + pthread_mutex_t *m_pMutex; +#if defined (DEBUG_PTHREAD_MUTEX_DEADLOCKS) + const char *m_function; + const char *m_file; + int m_line; + uint64_t m_lock_time; +#endif + }; + + + PThreadMutex() + { + int err; + err = ::pthread_mutex_init (&m_mutex, NULL); assert(err == 0); + } + + PThreadMutex(int type) + { + int err; + ::pthread_mutexattr_t attr; + err = ::pthread_mutexattr_init (&attr); assert(err == 0); + err = ::pthread_mutexattr_settype (&attr, type); assert(err == 0); + err = ::pthread_mutex_init (&m_mutex, &attr); assert(err == 0); + err = ::pthread_mutexattr_destroy (&attr); assert(err == 0); + } + + ~PThreadMutex() + { + int err; + err = ::pthread_mutex_destroy (&m_mutex); + if (err != 0) + { + err = Unlock(); + if (err == 0) + ::pthread_mutex_destroy (&m_mutex); + } + } + + pthread_mutex_t *Mutex() + { + return &m_mutex; + } + + int Lock() + { + return ::pthread_mutex_lock (&m_mutex); + } + + int Unlock() + { + return ::pthread_mutex_unlock (&m_mutex); + } + +protected: + pthread_mutex_t m_mutex; +}; + +#endif |