summaryrefslogtreecommitdiffstats
path: root/lldb/source/Host/macosx/Mutex.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Host/macosx/Mutex.cpp')
-rw-r--r--lldb/source/Host/macosx/Mutex.cpp244
1 files changed, 244 insertions, 0 deletions
diff --git a/lldb/source/Host/macosx/Mutex.cpp b/lldb/source/Host/macosx/Mutex.cpp
new file mode 100644
index 00000000000..ab0b67aa051
--- /dev/null
+++ b/lldb/source/Host/macosx/Mutex.cpp
@@ -0,0 +1,244 @@
+//===-- Mutex.cpp -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/Mutex.h"
+#include "lldb/Core/Log.h"
+
+#if 0
+#include "lldb/Host/Host.h"
+#define DEBUG_LOG(fmt, ...) printf(fmt, ## __VA_ARGS__)
+#else
+#define DEBUG_LOG(fmt, ...)
+#endif
+
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// Default constructor.
+//
+// This will create a scoped mutex locking object that doesn't have
+// a mutex to lock. One will need to be provided using the Reset()
+// method.
+//----------------------------------------------------------------------
+Mutex::Locker::Locker () :
+ m_mutex_ptr(NULL)
+{
+}
+
+//----------------------------------------------------------------------
+// Constructor with a Mutex object.
+//
+// This will create a scoped mutex locking object that extracts the
+// mutex owned by "m" and locks it.
+//----------------------------------------------------------------------
+Mutex::Locker::Locker (Mutex& m) :
+ m_mutex_ptr(m.GetMutex())
+{
+ if (m_mutex_ptr)
+ Mutex::Lock (m_mutex_ptr);
+}
+
+//----------------------------------------------------------------------
+// Constructor with a Mutex object pointer.
+//
+// This will create a scoped mutex locking object that extracts the
+// mutex owned by "m" and locks it.
+//----------------------------------------------------------------------
+Mutex::Locker::Locker (Mutex* m) :
+ m_mutex_ptr(m ? m->GetMutex() : NULL)
+{
+ if (m_mutex_ptr)
+ Mutex::Lock (m_mutex_ptr);
+}
+
+//----------------------------------------------------------------------
+// Constructor with a raw pthread mutex object pointer.
+//
+// This will create a scoped mutex locking object that locks "mutex"
+//----------------------------------------------------------------------
+Mutex::Locker::Locker (pthread_mutex_t *mutex_ptr) :
+ m_mutex_ptr(mutex_ptr)
+{
+ if (m_mutex_ptr)
+ Mutex::Lock (m_mutex_ptr);
+}
+
+//----------------------------------------------------------------------
+// Desstructor
+//
+// Unlocks any owned mutex object (if it is valid).
+//----------------------------------------------------------------------
+Mutex::Locker::~Locker ()
+{
+ if (m_mutex_ptr)
+ Mutex::Unlock (m_mutex_ptr);
+}
+
+//----------------------------------------------------------------------
+// Unlock the current mutex in this object (if this owns a valid
+// mutex) and lock the new "mutex" object if it is non-NULL.
+//----------------------------------------------------------------------
+void
+Mutex::Locker::Reset (pthread_mutex_t *mutex_ptr)
+{
+ if (m_mutex_ptr)
+ Mutex::Unlock (m_mutex_ptr);
+
+ m_mutex_ptr = mutex_ptr;
+ if (m_mutex_ptr)
+ Mutex::Lock (m_mutex_ptr);
+}
+
+bool
+Mutex::Locker::TryLock (pthread_mutex_t *mutex_ptr)
+{
+ if (m_mutex_ptr)
+ Mutex::Unlock (m_mutex_ptr);
+ m_mutex_ptr = NULL;
+ if (mutex_ptr)
+ {
+ if (Mutex::TryLock (mutex_ptr) == 0)
+ m_mutex_ptr = mutex_ptr;
+ }
+ return m_mutex_ptr != NULL;
+}
+
+//----------------------------------------------------------------------
+// Default constructor.
+//
+// Creates a pthread mutex with no attributes.
+//----------------------------------------------------------------------
+Mutex::Mutex () :
+ m_mutex()
+{
+ int err;
+ err = ::pthread_mutex_init (&m_mutex, NULL);
+ assert(err == 0);
+}
+
+//----------------------------------------------------------------------
+// Default constructor.
+//
+// Creates a pthread mutex with "type" as the mutex type.
+//----------------------------------------------------------------------
+Mutex::Mutex (Mutex::Type type) :
+ m_mutex()
+{
+ int err;
+ ::pthread_mutexattr_t attr;
+ err = ::pthread_mutexattr_init (&attr);
+ assert(err == 0);
+ switch (type)
+ {
+ case eMutexTypeNormal:
+ err = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_NORMAL);
+ break;
+
+ case eMutexTypeRecursive:
+ err = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+ break;
+
+ default:
+ err = -1;
+ break;
+ }
+ assert(err == 0);
+ err = ::pthread_mutex_init (&m_mutex, &attr);
+ assert(err == 0);
+ err = ::pthread_mutexattr_destroy (&attr);
+ assert(err == 0);
+}
+
+//----------------------------------------------------------------------
+// Destructor.
+//
+// Destroys the mutex owned by this object.
+//----------------------------------------------------------------------
+Mutex::~Mutex()
+{
+ int err;
+ err = ::pthread_mutex_destroy (&m_mutex);
+}
+
+//----------------------------------------------------------------------
+// Mutex get accessor.
+//----------------------------------------------------------------------
+pthread_mutex_t *
+Mutex::GetMutex()
+{
+ return &m_mutex;
+}
+
+int
+Mutex::Lock (pthread_mutex_t *mutex_ptr)
+{
+ DEBUG_LOG ("[%4.4x/%4.4x] pthread_mutex_lock (%p)...\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), mutex_ptr);
+ int err = ::pthread_mutex_lock (mutex_ptr);
+ DEBUG_LOG ("[%4.4x/%4.4x] pthread_mutex_lock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), mutex_ptr, err);
+ return err;
+}
+
+int
+Mutex::TryLock (pthread_mutex_t *mutex_ptr)
+{
+ int err = ::pthread_mutex_trylock (mutex_ptr);
+ DEBUG_LOG ("[%4.4x/%4.4x] pthread_mutex_trylock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), mutex_ptr, err);
+ return err;
+}
+
+int
+Mutex::Unlock (pthread_mutex_t *mutex_ptr)
+{
+ int err = ::pthread_mutex_unlock (mutex_ptr);
+ DEBUG_LOG ("[%4.4x/%4.4x] pthread_mutex_unlock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), mutex_ptr, err);
+ return err;
+}
+
+//----------------------------------------------------------------------
+// Locks the mutex owned by this object, if the mutex is already
+// locked, the calling thread will block until the mutex becomes
+// available.
+//
+// RETURNS
+// The error code from the pthread_mutex_lock() function call.
+//----------------------------------------------------------------------
+int
+Mutex::Lock()
+{
+ return Mutex::Lock (&m_mutex);
+}
+
+//----------------------------------------------------------------------
+// Attempts to lock the mutex owned by this object without blocking.
+// If the mutex is already locked, TryLock() will not block waiting
+// for the mutex, but will return an error condition.
+//
+// RETURNS
+// The error code from the pthread_mutex_trylock() function call.
+//----------------------------------------------------------------------
+int
+Mutex::TryLock()
+{
+ return Mutex::TryLock (&m_mutex);
+}
+
+//----------------------------------------------------------------------
+// If the current thread holds the lock on the owned mutex, then
+// Unlock() will unlock the mutex. Calling Unlock() on this object
+// that the calling thread does not hold will result in undefined
+// behavior.
+//
+// RETURNS
+// The error code from the pthread_mutex_unlock() function call.
+//----------------------------------------------------------------------
+int
+Mutex::Unlock()
+{
+ return Mutex::Unlock (&m_mutex);
+}
OpenPOWER on IntegriCloud