blob: e038102e98ca3726387e19f8c8d3f3f56cebb85a [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- Mutex.cpp -----------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Host/Mutex.h"
Chris Lattner24943d22010-06-08 16:52:24 +000011
12#if 0
Greg Clayton17f4bff2010-06-14 04:30:13 +000013// This logging is way too verbose to enable even for a log channel.
14// This logging can be enabled by changing the "#if 0", but should be
15// reverted prior to checking in.
16#include <cstdio>
Chris Lattner24943d22010-06-08 16:52:24 +000017#define DEBUG_LOG(fmt, ...) printf(fmt, ## __VA_ARGS__)
18#else
19#define DEBUG_LOG(fmt, ...)
20#endif
21
22using namespace lldb_private;
23
24//----------------------------------------------------------------------
25// Default constructor.
26//
27// This will create a scoped mutex locking object that doesn't have
28// a mutex to lock. One will need to be provided using the Reset()
29// method.
30//----------------------------------------------------------------------
31Mutex::Locker::Locker () :
32 m_mutex_ptr(NULL)
33{
34}
35
36//----------------------------------------------------------------------
37// Constructor with a Mutex object.
38//
39// This will create a scoped mutex locking object that extracts the
40// mutex owned by "m" and locks it.
41//----------------------------------------------------------------------
42Mutex::Locker::Locker (Mutex& m) :
43 m_mutex_ptr(m.GetMutex())
44{
45 if (m_mutex_ptr)
46 Mutex::Lock (m_mutex_ptr);
47}
48
49//----------------------------------------------------------------------
50// Constructor with a Mutex object pointer.
51//
52// This will create a scoped mutex locking object that extracts the
53// mutex owned by "m" and locks it.
54//----------------------------------------------------------------------
55Mutex::Locker::Locker (Mutex* m) :
56 m_mutex_ptr(m ? m->GetMutex() : NULL)
57{
58 if (m_mutex_ptr)
59 Mutex::Lock (m_mutex_ptr);
60}
61
62//----------------------------------------------------------------------
63// Constructor with a raw pthread mutex object pointer.
64//
65// This will create a scoped mutex locking object that locks "mutex"
66//----------------------------------------------------------------------
67Mutex::Locker::Locker (pthread_mutex_t *mutex_ptr) :
68 m_mutex_ptr(mutex_ptr)
69{
70 if (m_mutex_ptr)
71 Mutex::Lock (m_mutex_ptr);
72}
73
74//----------------------------------------------------------------------
75// Desstructor
76//
77// Unlocks any owned mutex object (if it is valid).
78//----------------------------------------------------------------------
79Mutex::Locker::~Locker ()
80{
Greg Clayton1a679462010-09-03 19:15:43 +000081 Reset();
Chris Lattner24943d22010-06-08 16:52:24 +000082}
83
84//----------------------------------------------------------------------
85// Unlock the current mutex in this object (if this owns a valid
86// mutex) and lock the new "mutex" object if it is non-NULL.
87//----------------------------------------------------------------------
88void
89Mutex::Locker::Reset (pthread_mutex_t *mutex_ptr)
90{
Greg Clayton1a679462010-09-03 19:15:43 +000091 // We already have this mutex locked or both are NULL...
92 if (m_mutex_ptr == mutex_ptr)
93 return;
94
Chris Lattner24943d22010-06-08 16:52:24 +000095 if (m_mutex_ptr)
96 Mutex::Unlock (m_mutex_ptr);
97
98 m_mutex_ptr = mutex_ptr;
99 if (m_mutex_ptr)
100 Mutex::Lock (m_mutex_ptr);
101}
102
103bool
104Mutex::Locker::TryLock (pthread_mutex_t *mutex_ptr)
105{
Greg Clayton1a679462010-09-03 19:15:43 +0000106 // We already have this mutex locked!
107 if (m_mutex_ptr == mutex_ptr)
108 return true;
109
110 Reset ();
111
Chris Lattner24943d22010-06-08 16:52:24 +0000112 if (mutex_ptr)
113 {
114 if (Mutex::TryLock (mutex_ptr) == 0)
115 m_mutex_ptr = mutex_ptr;
116 }
117 return m_mutex_ptr != NULL;
118}
119
120//----------------------------------------------------------------------
121// Default constructor.
122//
123// Creates a pthread mutex with no attributes.
124//----------------------------------------------------------------------
125Mutex::Mutex () :
126 m_mutex()
127{
128 int err;
129 err = ::pthread_mutex_init (&m_mutex, NULL);
130 assert(err == 0);
131}
132
133//----------------------------------------------------------------------
134// Default constructor.
135//
136// Creates a pthread mutex with "type" as the mutex type.
137//----------------------------------------------------------------------
138Mutex::Mutex (Mutex::Type type) :
139 m_mutex()
140{
141 int err;
142 ::pthread_mutexattr_t attr;
143 err = ::pthread_mutexattr_init (&attr);
144 assert(err == 0);
145 switch (type)
146 {
147 case eMutexTypeNormal:
148 err = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_NORMAL);
149 break;
150
151 case eMutexTypeRecursive:
152 err = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
153 break;
154
155 default:
156 err = -1;
157 break;
158 }
159 assert(err == 0);
160 err = ::pthread_mutex_init (&m_mutex, &attr);
161 assert(err == 0);
162 err = ::pthread_mutexattr_destroy (&attr);
163 assert(err == 0);
164}
165
166//----------------------------------------------------------------------
167// Destructor.
168//
169// Destroys the mutex owned by this object.
170//----------------------------------------------------------------------
171Mutex::~Mutex()
172{
173 int err;
174 err = ::pthread_mutex_destroy (&m_mutex);
175}
176
177//----------------------------------------------------------------------
178// Mutex get accessor.
179//----------------------------------------------------------------------
180pthread_mutex_t *
181Mutex::GetMutex()
182{
183 return &m_mutex;
184}
185
186int
187Mutex::Lock (pthread_mutex_t *mutex_ptr)
188{
189 DEBUG_LOG ("[%4.4x/%4.4x] pthread_mutex_lock (%p)...\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), mutex_ptr);
190 int err = ::pthread_mutex_lock (mutex_ptr);
191 DEBUG_LOG ("[%4.4x/%4.4x] pthread_mutex_lock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), mutex_ptr, err);
192 return err;
193}
194
195int
196Mutex::TryLock (pthread_mutex_t *mutex_ptr)
197{
198 int err = ::pthread_mutex_trylock (mutex_ptr);
199 DEBUG_LOG ("[%4.4x/%4.4x] pthread_mutex_trylock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), mutex_ptr, err);
200 return err;
201}
202
203int
204Mutex::Unlock (pthread_mutex_t *mutex_ptr)
205{
206 int err = ::pthread_mutex_unlock (mutex_ptr);
207 DEBUG_LOG ("[%4.4x/%4.4x] pthread_mutex_unlock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), mutex_ptr, err);
208 return err;
209}
210
211//----------------------------------------------------------------------
212// Locks the mutex owned by this object, if the mutex is already
213// locked, the calling thread will block until the mutex becomes
214// available.
215//
216// RETURNS
217// The error code from the pthread_mutex_lock() function call.
218//----------------------------------------------------------------------
219int
220Mutex::Lock()
221{
222 return Mutex::Lock (&m_mutex);
223}
224
225//----------------------------------------------------------------------
226// Attempts to lock the mutex owned by this object without blocking.
227// If the mutex is already locked, TryLock() will not block waiting
228// for the mutex, but will return an error condition.
229//
230// RETURNS
231// The error code from the pthread_mutex_trylock() function call.
232//----------------------------------------------------------------------
233int
234Mutex::TryLock()
235{
236 return Mutex::TryLock (&m_mutex);
237}
238
239//----------------------------------------------------------------------
240// If the current thread holds the lock on the owned mutex, then
241// Unlock() will unlock the mutex. Calling Unlock() on this object
242// that the calling thread does not hold will result in undefined
243// behavior.
244//
245// RETURNS
246// The error code from the pthread_mutex_unlock() function call.
247//----------------------------------------------------------------------
248int
249Mutex::Unlock()
250{
251 return Mutex::Unlock (&m_mutex);
252}