blob: 3f1c83066994aec304cf47f8fb2b7272e09823d4 [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{
81 if (m_mutex_ptr)
82 Mutex::Unlock (m_mutex_ptr);
83}
84
85//----------------------------------------------------------------------
86// Unlock the current mutex in this object (if this owns a valid
87// mutex) and lock the new "mutex" object if it is non-NULL.
88//----------------------------------------------------------------------
89void
90Mutex::Locker::Reset (pthread_mutex_t *mutex_ptr)
91{
92 if (m_mutex_ptr)
93 Mutex::Unlock (m_mutex_ptr);
94
95 m_mutex_ptr = mutex_ptr;
96 if (m_mutex_ptr)
97 Mutex::Lock (m_mutex_ptr);
98}
99
100bool
101Mutex::Locker::TryLock (pthread_mutex_t *mutex_ptr)
102{
103 if (m_mutex_ptr)
104 Mutex::Unlock (m_mutex_ptr);
105 m_mutex_ptr = NULL;
106 if (mutex_ptr)
107 {
108 if (Mutex::TryLock (mutex_ptr) == 0)
109 m_mutex_ptr = mutex_ptr;
110 }
111 return m_mutex_ptr != NULL;
112}
113
114//----------------------------------------------------------------------
115// Default constructor.
116//
117// Creates a pthread mutex with no attributes.
118//----------------------------------------------------------------------
119Mutex::Mutex () :
120 m_mutex()
121{
122 int err;
123 err = ::pthread_mutex_init (&m_mutex, NULL);
124 assert(err == 0);
125}
126
127//----------------------------------------------------------------------
128// Default constructor.
129//
130// Creates a pthread mutex with "type" as the mutex type.
131//----------------------------------------------------------------------
132Mutex::Mutex (Mutex::Type type) :
133 m_mutex()
134{
135 int err;
136 ::pthread_mutexattr_t attr;
137 err = ::pthread_mutexattr_init (&attr);
138 assert(err == 0);
139 switch (type)
140 {
141 case eMutexTypeNormal:
142 err = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_NORMAL);
143 break;
144
145 case eMutexTypeRecursive:
146 err = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
147 break;
148
149 default:
150 err = -1;
151 break;
152 }
153 assert(err == 0);
154 err = ::pthread_mutex_init (&m_mutex, &attr);
155 assert(err == 0);
156 err = ::pthread_mutexattr_destroy (&attr);
157 assert(err == 0);
158}
159
160//----------------------------------------------------------------------
161// Destructor.
162//
163// Destroys the mutex owned by this object.
164//----------------------------------------------------------------------
165Mutex::~Mutex()
166{
167 int err;
168 err = ::pthread_mutex_destroy (&m_mutex);
169}
170
171//----------------------------------------------------------------------
172// Mutex get accessor.
173//----------------------------------------------------------------------
174pthread_mutex_t *
175Mutex::GetMutex()
176{
177 return &m_mutex;
178}
179
180int
181Mutex::Lock (pthread_mutex_t *mutex_ptr)
182{
183 DEBUG_LOG ("[%4.4x/%4.4x] pthread_mutex_lock (%p)...\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), mutex_ptr);
184 int err = ::pthread_mutex_lock (mutex_ptr);
185 DEBUG_LOG ("[%4.4x/%4.4x] pthread_mutex_lock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), mutex_ptr, err);
186 return err;
187}
188
189int
190Mutex::TryLock (pthread_mutex_t *mutex_ptr)
191{
192 int err = ::pthread_mutex_trylock (mutex_ptr);
193 DEBUG_LOG ("[%4.4x/%4.4x] pthread_mutex_trylock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), mutex_ptr, err);
194 return err;
195}
196
197int
198Mutex::Unlock (pthread_mutex_t *mutex_ptr)
199{
200 int err = ::pthread_mutex_unlock (mutex_ptr);
201 DEBUG_LOG ("[%4.4x/%4.4x] pthread_mutex_unlock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), mutex_ptr, err);
202 return err;
203}
204
205//----------------------------------------------------------------------
206// Locks the mutex owned by this object, if the mutex is already
207// locked, the calling thread will block until the mutex becomes
208// available.
209//
210// RETURNS
211// The error code from the pthread_mutex_lock() function call.
212//----------------------------------------------------------------------
213int
214Mutex::Lock()
215{
216 return Mutex::Lock (&m_mutex);
217}
218
219//----------------------------------------------------------------------
220// Attempts to lock the mutex owned by this object without blocking.
221// If the mutex is already locked, TryLock() will not block waiting
222// for the mutex, but will return an error condition.
223//
224// RETURNS
225// The error code from the pthread_mutex_trylock() function call.
226//----------------------------------------------------------------------
227int
228Mutex::TryLock()
229{
230 return Mutex::TryLock (&m_mutex);
231}
232
233//----------------------------------------------------------------------
234// If the current thread holds the lock on the owned mutex, then
235// Unlock() will unlock the mutex. Calling Unlock() on this object
236// that the calling thread does not hold will result in undefined
237// behavior.
238//
239// RETURNS
240// The error code from the pthread_mutex_unlock() function call.
241//----------------------------------------------------------------------
242int
243Mutex::Unlock()
244{
245 return Mutex::Unlock (&m_mutex);
246}