summaryrefslogtreecommitdiff
path: root/tools/debugserver/source/PThreadMutex.h
diff options
context:
space:
mode:
Diffstat (limited to 'tools/debugserver/source/PThreadMutex.h')
-rw-r--r--tools/debugserver/source/PThreadMutex.h148
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