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"
20 // This logging is way too verbose to enable even for a log channel.
21 // This logging can be enabled by changing the "#if 0", but should be
22 // reverted prior to checking in.
24 #define DEBUG_LOG(fmt, ...) printf(fmt, ## __VA_ARGS__)
26 #define DEBUG_LOG(fmt, ...)
29 // Enable extra mutex error checking
30 #ifdef LLDB_CONFIGURATION_DEBUG
31 #define ENABLE_MUTEX_ERROR_CHECKING 1
35 #if ENABLE_MUTEX_ERROR_CHECKING
40 eMutexActionInitialized,
41 eMutexActionDestroyed,
42 eMutexActionAssertInitialized
46 error_check_mutex (pthread_mutex_t *m, MutexAction action)
48 typedef std::set<pthread_mutex_t *> mutex_set;
49 static pthread_mutex_t g_mutex_set_mutex = PTHREAD_MUTEX_INITIALIZER;
50 static mutex_set g_initialized_mutex_set;
51 static mutex_set g_destroyed_mutex_set;
55 // Manually call lock so we don't to any of this error checking
56 err = ::pthread_mutex_lock (&g_mutex_set_mutex);
60 case eMutexActionInitialized:
61 // Make sure this isn't already in our initialized mutex set...
62 assert (g_initialized_mutex_set.find(m) == g_initialized_mutex_set.end());
63 // Remove this from the destroyed set in case it was ever in there
64 g_destroyed_mutex_set.erase(m);
65 // Add the mutex to the initialized set
66 g_initialized_mutex_set.insert(m);
69 case eMutexActionDestroyed:
70 // Make sure this isn't already in our destroyed mutex set...
71 assert (g_destroyed_mutex_set.find(m) == g_destroyed_mutex_set.end());
72 // Remove this from the initialized so we can put it into the destroyed set
73 g_initialized_mutex_set.erase(m);
74 // Add the mutex to the destroyed set
75 g_destroyed_mutex_set.insert(m);
77 case eMutexActionAssertInitialized:
78 // This function will return true if "m" is in the initialized mutex set
79 success = g_initialized_mutex_set.find(m) != g_initialized_mutex_set.end();
83 // Manually call unlock so we don't to any of this error checking
84 err = ::pthread_mutex_unlock (&g_mutex_set_mutex);
91 using namespace lldb_private;
93 //----------------------------------------------------------------------
94 // Default constructor.
96 // This will create a scoped mutex locking object that doesn't have
97 // a mutex to lock. One will need to be provided using the Reset()
99 //----------------------------------------------------------------------
100 Mutex::Locker::Locker () :
105 //----------------------------------------------------------------------
106 // Constructor with a Mutex object.
108 // This will create a scoped mutex locking object that extracts the
109 // mutex owned by "m" and locks it.
110 //----------------------------------------------------------------------
111 Mutex::Locker::Locker (Mutex& m) :
117 //----------------------------------------------------------------------
118 // Constructor with a Mutex object pointer.
120 // This will create a scoped mutex locking object that extracts the
121 // mutex owned by "m" and locks it.
122 //----------------------------------------------------------------------
123 Mutex::Locker::Locker (Mutex* m) :
130 //----------------------------------------------------------------------
133 // Unlocks any owned mutex object (if it is valid).
134 //----------------------------------------------------------------------
135 Mutex::Locker::~Locker ()
140 //----------------------------------------------------------------------
141 // Unlock the current mutex in this object (if this owns a valid
142 // mutex) and lock the new "mutex" object if it is non-NULL.
143 //----------------------------------------------------------------------
145 Mutex::Locker::Lock (Mutex &mutex)
147 // We already have this mutex locked or both are NULL...
148 if (m_mutex_ptr == &mutex)
153 m_mutex_ptr = &mutex;
158 Mutex::Locker::Unlock ()
162 m_mutex_ptr->Unlock ();
168 Mutex::Locker::TryLock (Mutex &mutex, const char *failure_message)
170 // We already have this mutex locked!
171 if (m_mutex_ptr == &mutex)
176 if (mutex.TryLock(failure_message) == 0)
177 m_mutex_ptr = &mutex;
179 return m_mutex_ptr != NULL;
184 //----------------------------------------------------------------------
185 // Default constructor.
187 // Creates a pthread mutex with no attributes.
188 //----------------------------------------------------------------------
193 err = ::pthread_mutex_init (&m_mutex, NULL);
194 #if ENABLE_MUTEX_ERROR_CHECKING
196 error_check_mutex (&m_mutex, eMutexActionInitialized);
201 //----------------------------------------------------------------------
202 // Default constructor.
204 // Creates a pthread mutex with "type" as the mutex type.
205 //----------------------------------------------------------------------
206 Mutex::Mutex (Mutex::Type type) :
210 ::pthread_mutexattr_t attr;
211 err = ::pthread_mutexattr_init (&attr);
215 case eMutexTypeNormal:
216 #if ENABLE_MUTEX_ERROR_CHECKING
217 err = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK);
219 err = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_NORMAL);
223 case eMutexTypeRecursive:
224 err = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
228 err = ::pthread_mutex_init (&m_mutex, &attr);
229 #if ENABLE_MUTEX_ERROR_CHECKING
231 error_check_mutex (&m_mutex, eMutexActionInitialized);
234 err = ::pthread_mutexattr_destroy (&attr);
238 //----------------------------------------------------------------------
241 // Destroys the mutex owned by this object.
242 //----------------------------------------------------------------------
245 int err = ::pthread_mutex_destroy (&m_mutex);
247 #if ENABLE_MUTEX_ERROR_CHECKING
249 error_check_mutex (&m_mutex, eMutexActionDestroyed);
252 Host::SetCrashDescriptionWithFormat ("%s error: pthread_mutex_destroy() => err = %i (%s)", __PRETTY_FUNCTION__, err, strerror(err));
255 memset (&m_mutex, '\xba', sizeof(m_mutex));
259 //----------------------------------------------------------------------
260 // Locks the mutex owned by this object, if the mutex is already
261 // locked, the calling thread will block until the mutex becomes
265 // The error code from the pthread_mutex_lock() function call.
266 //----------------------------------------------------------------------
270 DEBUG_LOG ("[%4.4" PRIx64 "/%4.4" PRIx64 "] pthread_mutex_lock (%p)...\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex);
272 #if ENABLE_MUTEX_ERROR_CHECKING
273 error_check_mutex (&m_mutex, eMutexActionAssertInitialized);
276 int err = ::pthread_mutex_lock (&m_mutex);
279 #if ENABLE_MUTEX_ERROR_CHECKING
282 Host::SetCrashDescriptionWithFormat ("%s error: pthread_mutex_lock(%p) => err = %i (%s)", __PRETTY_FUNCTION__, &m_mutex, err, strerror(err));
286 DEBUG_LOG ("[%4.4" PRIx64 "/%4.4" PRIx64 "] pthread_mutex_lock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
290 //----------------------------------------------------------------------
291 // Attempts to lock the mutex owned by this object without blocking.
292 // If the mutex is already locked, TryLock() will not block waiting
293 // for the mutex, but will return an error condition.
296 // The error code from the pthread_mutex_trylock() function call.
297 //----------------------------------------------------------------------
299 Mutex::TryLock(const char *failure_message)
301 #if ENABLE_MUTEX_ERROR_CHECKING
302 error_check_mutex (&m_mutex, eMutexActionAssertInitialized);
305 int err = ::pthread_mutex_trylock (&m_mutex);
306 DEBUG_LOG ("[%4.4" PRIx64 "/%4.4" PRIx64 "] pthread_mutex_trylock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
310 //----------------------------------------------------------------------
311 // If the current thread holds the lock on the owned mutex, then
312 // Unlock() will unlock the mutex. Calling Unlock() on this object
313 // that the calling thread does not hold will result in undefined
317 // The error code from the pthread_mutex_unlock() function call.
318 //----------------------------------------------------------------------
322 #if ENABLE_MUTEX_ERROR_CHECKING
323 error_check_mutex (&m_mutex, eMutexActionAssertInitialized);
326 int err = ::pthread_mutex_unlock (&m_mutex);
328 #if ENABLE_MUTEX_ERROR_CHECKING
331 Host::SetCrashDescriptionWithFormat ("%s error: pthread_mutex_unlock(%p) => err = %i (%s)", __PRETTY_FUNCTION__, &m_mutex, err, strerror(err));
335 DEBUG_LOG ("[%4.4" PRIx64 "/%4.4" PRIx64 "] pthread_mutex_unlock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
341 //----------------------------------------------------------------------
342 // Mutex get accessor.
343 //----------------------------------------------------------------------
350 #ifdef LLDB_CONFIGURATION_DEBUG
352 TrackingMutex::Unlock ()
354 if (!m_failure_message.empty())
355 Host::SetCrashDescriptionWithFormat ("Unlocking lock (on thread %p) that thread: %p failed to get: %s",
358 m_failure_message.c_str());
359 assert (m_failure_message.empty());
360 return Mutex::Unlock();
364 LoggingMutex::Lock ()
366 printf("locking mutex %p by [%4.4" PRIx64 "/%4.4" PRIx64 "]...", this, Host::GetCurrentProcessID(), Host::GetCurrentThreadID());
367 int x = Mutex::Lock();
374 LoggingMutex::Unlock ()
376 printf("unlocking mutex %p by [%4.4" PRIx64 "/%4.4" PRIx64 "]...", this, Host::GetCurrentProcessID(), Host::GetCurrentThreadID());
377 int x = Mutex::Unlock();
384 LoggingMutex::TryLock (const char *failure_message)
386 printf("trylocking mutex %p by [%4.4" PRIx64 "/%4.4" PRIx64 "]...", this, Host::GetCurrentProcessID(), Host::GetCurrentThreadID());
387 int x = Mutex::TryLock(failure_message);