diff options
Diffstat (limited to 'lldb/source/Host/macosx/Mutex.cpp')
-rw-r--r-- | lldb/source/Host/macosx/Mutex.cpp | 244 |
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); +} |