1 //===-- Mutex.cpp -----------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Host/Mutex.h"
11 #include "lldb/Host/Host.h"
18 // This logging is way too verbose to enable even for a log channel.
19 // This logging can be enabled by changing the "#if 0", but should be
20 // reverted prior to checking in.
22 #define DEBUG_LOG(fmt, ...) printf(fmt, ## __VA_ARGS__)
24 #define DEBUG_LOG(fmt, ...)
27 // Enable extra mutex error checking
28 #ifdef LLDB_CONFIGURATION_DEBUG
29 #define ENABLE_MUTEX_ERROR_CHECKING 1
33 #if ENABLE_MUTEX_ERROR_CHECKING
38 eMutexActionInitialized,
39 eMutexActionDestroyed,
40 eMutexActionAssertInitialized
44 error_check_mutex (pthread_mutex_t *m, MutexAction action)
46 typedef std::set<pthread_mutex_t *> mutex_set;
47 static pthread_mutex_t g_mutex_set_mutex = PTHREAD_MUTEX_INITIALIZER;
48 static mutex_set g_initialized_mutex_set;
49 static mutex_set g_destroyed_mutex_set;
53 // Manually call lock so we don't to any of this error checking
54 err = ::pthread_mutex_lock (&g_mutex_set_mutex);
58 case eMutexActionInitialized:
59 // Make sure this isn't already in our initialized mutex set...
60 assert (g_initialized_mutex_set.find(m) == g_initialized_mutex_set.end());
61 // Remove this from the destroyed set in case it was ever in there
62 g_destroyed_mutex_set.erase(m);
63 // Add the mutex to the initialized set
64 g_initialized_mutex_set.insert(m);
67 case eMutexActionDestroyed:
68 // Make sure this isn't already in our destroyed mutex set...
69 assert (g_destroyed_mutex_set.find(m) == g_destroyed_mutex_set.end());
70 // Remove this from the initialized so we can put it into the destroyed set
71 g_initialized_mutex_set.erase(m);
72 // Add the mutex to the destroyed set
73 g_destroyed_mutex_set.insert(m);
75 case eMutexActionAssertInitialized:
76 // This function will return true if "m" is in the initialized mutex set
77 success = g_initialized_mutex_set.find(m) != g_initialized_mutex_set.end();
81 // Manually call unlock so we don't to any of this error checking
82 err = ::pthread_mutex_unlock (&g_mutex_set_mutex);
89 using namespace lldb_private;
91 //----------------------------------------------------------------------
92 // Default constructor.
94 // This will create a scoped mutex locking object that doesn't have
95 // a mutex to lock. One will need to be provided using the Reset()
97 //----------------------------------------------------------------------
98 Mutex::Locker::Locker () :
103 //----------------------------------------------------------------------
104 // Constructor with a Mutex object.
106 // This will create a scoped mutex locking object that extracts the
107 // mutex owned by "m" and locks it.
108 //----------------------------------------------------------------------
109 Mutex::Locker::Locker (Mutex& m) :
115 //----------------------------------------------------------------------
116 // Constructor with a Mutex object pointer.
118 // This will create a scoped mutex locking object that extracts the
119 // mutex owned by "m" and locks it.
120 //----------------------------------------------------------------------
121 Mutex::Locker::Locker (Mutex* m) :
128 //----------------------------------------------------------------------
131 // Unlocks any owned mutex object (if it is valid).
132 //----------------------------------------------------------------------
133 Mutex::Locker::~Locker ()
138 //----------------------------------------------------------------------
139 // Unlock the current mutex in this object (if this owns a valid
140 // mutex) and lock the new "mutex" object if it is non-NULL.
141 //----------------------------------------------------------------------
143 Mutex::Locker::Lock (Mutex &mutex)
145 // We already have this mutex locked or both are NULL...
146 if (m_mutex_ptr == &mutex)
151 m_mutex_ptr = &mutex;
156 Mutex::Locker::Unlock ()
160 m_mutex_ptr->Unlock ();
166 Mutex::Locker::TryLock (Mutex &mutex, const char *failure_message)
168 // We already have this mutex locked!
169 if (m_mutex_ptr == &mutex)
174 if (mutex.TryLock(failure_message) == 0)
175 m_mutex_ptr = &mutex;
177 return m_mutex_ptr != NULL;
180 //----------------------------------------------------------------------
181 // Default constructor.
183 // Creates a pthread mutex with no attributes.
184 //----------------------------------------------------------------------
189 err = ::pthread_mutex_init (&m_mutex, NULL);
190 #if ENABLE_MUTEX_ERROR_CHECKING
192 error_check_mutex (&m_mutex, eMutexActionInitialized);
197 //----------------------------------------------------------------------
198 // Default constructor.
200 // Creates a pthread mutex with "type" as the mutex type.
201 //----------------------------------------------------------------------
202 Mutex::Mutex (Mutex::Type type) :
206 ::pthread_mutexattr_t attr;
207 err = ::pthread_mutexattr_init (&attr);
211 case eMutexTypeNormal:
212 #if ENABLE_MUTEX_ERROR_CHECKING
213 err = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK);
215 err = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_NORMAL);
219 case eMutexTypeRecursive:
220 err = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
224 err = ::pthread_mutex_init (&m_mutex, &attr);
225 #if ENABLE_MUTEX_ERROR_CHECKING
227 error_check_mutex (&m_mutex, eMutexActionInitialized);
230 err = ::pthread_mutexattr_destroy (&attr);
234 //----------------------------------------------------------------------
237 // Destroys the mutex owned by this object.
238 //----------------------------------------------------------------------
241 int err = ::pthread_mutex_destroy (&m_mutex);
243 #if ENABLE_MUTEX_ERROR_CHECKING
245 error_check_mutex (&m_mutex, eMutexActionDestroyed);
248 Host::SetCrashDescriptionWithFormat ("%s error: pthread_mutex_destroy() => err = %i (%s)", __PRETTY_FUNCTION__, err, strerror(err));
251 memset (&m_mutex, '\xba', sizeof(m_mutex));
255 //----------------------------------------------------------------------
256 // Mutex get accessor.
257 //----------------------------------------------------------------------
264 //----------------------------------------------------------------------
265 // Locks the mutex owned by this object, if the mutex is already
266 // locked, the calling thread will block until the mutex becomes
270 // The error code from the pthread_mutex_lock() function call.
271 //----------------------------------------------------------------------
275 DEBUG_LOG ("[%4.4" PRIx64 "/%4.4" PRIx64 "] pthread_mutex_lock (%p)...\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex);
277 #if ENABLE_MUTEX_ERROR_CHECKING
278 error_check_mutex (&m_mutex, eMutexActionAssertInitialized);
281 int err = ::pthread_mutex_lock (&m_mutex);
284 #if ENABLE_MUTEX_ERROR_CHECKING
287 Host::SetCrashDescriptionWithFormat ("%s error: pthread_mutex_lock(%p) => err = %i (%s)", __PRETTY_FUNCTION__, &m_mutex, err, strerror(err));
291 DEBUG_LOG ("[%4.4" PRIx64 "/%4.4" PRIx64 "] pthread_mutex_lock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
295 //----------------------------------------------------------------------
296 // Attempts to lock the mutex owned by this object without blocking.
297 // If the mutex is already locked, TryLock() will not block waiting
298 // for the mutex, but will return an error condition.
301 // The error code from the pthread_mutex_trylock() function call.
302 //----------------------------------------------------------------------
304 Mutex::TryLock(const char *failure_message)
306 #if ENABLE_MUTEX_ERROR_CHECKING
307 error_check_mutex (&m_mutex, eMutexActionAssertInitialized);
310 int err = ::pthread_mutex_trylock (&m_mutex);
311 DEBUG_LOG ("[%4.4" PRIx64 "/%4.4" PRIx64 "] pthread_mutex_trylock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
315 //----------------------------------------------------------------------
316 // If the current thread holds the lock on the owned mutex, then
317 // Unlock() will unlock the mutex. Calling Unlock() on this object
318 // that the calling thread does not hold will result in undefined
322 // The error code from the pthread_mutex_unlock() function call.
323 //----------------------------------------------------------------------
327 #if ENABLE_MUTEX_ERROR_CHECKING
328 error_check_mutex (&m_mutex, eMutexActionAssertInitialized);
331 int err = ::pthread_mutex_unlock (&m_mutex);
333 #if ENABLE_MUTEX_ERROR_CHECKING
336 Host::SetCrashDescriptionWithFormat ("%s error: pthread_mutex_unlock(%p) => err = %i (%s)", __PRETTY_FUNCTION__, &m_mutex, err, strerror(err));
340 DEBUG_LOG ("[%4.4" PRIx64 "/%4.4" PRIx64 "] pthread_mutex_unlock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
344 #ifdef LLDB_CONFIGURATION_DEBUG
346 TrackingMutex::Unlock ()
348 if (!m_failure_message.empty())
349 Host::SetCrashDescriptionWithFormat ("Unlocking lock (on thread %p) that thread: %p failed to get: %s",
352 m_failure_message.c_str());
353 assert (m_failure_message.empty());
354 return Mutex::Unlock();
358 LoggingMutex::Lock ()
360 printf("locking mutex %p by [%4.4" PRIx64 "/%4.4" PRIx64 "]...", this, Host::GetCurrentProcessID(), Host::GetCurrentThreadID());
361 int x = Mutex::Lock();
368 LoggingMutex::Unlock ()
370 printf("unlocking mutex %p by [%4.4" PRIx64 "/%4.4" PRIx64 "]...", this, Host::GetCurrentProcessID(), Host::GetCurrentThreadID());
371 int x = Mutex::Unlock();
378 LoggingMutex::TryLock (const char *failure_message)
380 printf("trylocking mutex %p by [%4.4" PRIx64 "/%4.4" PRIx64 "]...", this, Host::GetCurrentProcessID(), Host::GetCurrentThreadID());
381 int x = Mutex::TryLock(failure_message);