blob: af2b3524ebd2d2e8717c88937546b692938df39f [file] [log] [blame]
Elliott Hughes8daa0922011-09-11 13:46:25 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_SRC_MUTEX_H_
18#define ART_SRC_MUTEX_H_
19
20#include <pthread.h>
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080021#include <stdint.h>
Elliott Hughesffb465f2012-03-01 18:46:05 -080022
23#include <iosfwd>
Elliott Hughes8daa0922011-09-11 13:46:25 -070024#include <string>
25
Ian Rogers00f7d0e2012-07-19 15:28:27 -070026#include "globals.h"
Ian Rogers81d425b2012-09-27 16:03:43 -070027#include "locks.h"
Elliott Hughes8daa0922011-09-11 13:46:25 -070028#include "macros.h"
Ian Rogers81d425b2012-09-27 16:03:43 -070029#include "thread.h"
30
31#define ART_USE_FUTEXES 0
Elliott Hughes8daa0922011-09-11 13:46:25 -070032
Ian Rogers66aee5c2012-08-15 17:17:47 -070033// Currently Darwin doesn't support locks with timeouts.
34#if !defined(__APPLE__)
35#define HAVE_TIMED_RWLOCK 1
36#else
37#define HAVE_TIMED_RWLOCK 0
38#endif
39
Elliott Hughes8daa0922011-09-11 13:46:25 -070040namespace art {
41
Ian Rogers25fd14b2012-09-05 10:56:38 -070042const bool kDebugLocking = kIsDebugBuild;
43
Ian Rogers00f7d0e2012-07-19 15:28:27 -070044// Base class for all Mutex implementations
45class BaseMutex {
46 public:
47 const std::string& GetName() const {
48 return name_;
49 }
50
51 virtual bool IsMutex() const { return false; }
52 virtual bool IsReaderWriterMutex() const { return false; }
53
54 protected:
55 friend class ConditionVariable;
56
Ian Rogers81d425b2012-09-27 16:03:43 -070057 BaseMutex(const char* name, LockLevel level);
Ian Rogers00f7d0e2012-07-19 15:28:27 -070058 virtual ~BaseMutex() {}
Ian Rogers81d425b2012-09-27 16:03:43 -070059 void RegisterAsLocked(Thread* self);
60 void RegisterAsUnlocked(Thread* self);
61 void CheckSafeToWait(Thread* self);
Ian Rogers00f7d0e2012-07-19 15:28:27 -070062
Ian Rogers81d425b2012-09-27 16:03:43 -070063 const LockLevel level_; // Support for lock hierarchy.
Ian Rogers00f7d0e2012-07-19 15:28:27 -070064 const std::string name_;
65};
66
67// A Mutex is used to achieve mutual exclusion between threads. A Mutex can be used to gain
68// exclusive access to what it guards. A Mutex can be in one of two states:
69// - Free - not owned by any thread,
70// - Exclusive - owned by a single thread.
71//
72// The effect of locking and unlocking operations on the state is:
73// State | ExclusiveLock | ExclusiveUnlock
74// -------------------------------------------
75// Free | Exclusive | error
76// Exclusive | Block* | Free
77// * Mutex is not reentrant and so an attempt to ExclusiveLock on the same thread will result in
78// an error. Being non-reentrant simplifies Waiting on ConditionVariables.
79class LOCKABLE Mutex : public BaseMutex {
80 public:
Ian Rogers81d425b2012-09-27 16:03:43 -070081 explicit Mutex(const char* name, LockLevel level = kDefaultMutexLevel, bool recursive = false);
Elliott Hughes8daa0922011-09-11 13:46:25 -070082 ~Mutex();
83
Ian Rogers00f7d0e2012-07-19 15:28:27 -070084 virtual bool IsMutex() const { return true; }
Elliott Hughes8daa0922011-09-11 13:46:25 -070085
Ian Rogers00f7d0e2012-07-19 15:28:27 -070086 // Block until mutex is free then acquire exclusive access.
Ian Rogers81d425b2012-09-27 16:03:43 -070087 void ExclusiveLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION();
88 void Lock(Thread* self) EXCLUSIVE_LOCK_FUNCTION() { ExclusiveLock(self); }
Elliott Hughes8daa0922011-09-11 13:46:25 -070089
Ian Rogers00f7d0e2012-07-19 15:28:27 -070090 // Returns true if acquires exclusive access, false otherwise.
Ian Rogers81d425b2012-09-27 16:03:43 -070091 bool ExclusiveTryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true);
92 bool TryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true) { return ExclusiveTryLock(self); }
Elliott Hughes8daa0922011-09-11 13:46:25 -070093
Ian Rogers00f7d0e2012-07-19 15:28:27 -070094 // Release exclusive access.
Ian Rogers81d425b2012-09-27 16:03:43 -070095 void ExclusiveUnlock(Thread* self) UNLOCK_FUNCTION();
96 void Unlock(Thread* self) UNLOCK_FUNCTION() { ExclusiveUnlock(self); }
Elliott Hughes8daa0922011-09-11 13:46:25 -070097
Ian Rogers00f7d0e2012-07-19 15:28:27 -070098 // Is the current thread the exclusive holder of the Mutex.
Ian Rogers81d425b2012-09-27 16:03:43 -070099 bool IsExclusiveHeld(const Thread* self) const;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700100
101 // Assert that the Mutex is exclusively held by the current thread.
Ian Rogers81d425b2012-09-27 16:03:43 -0700102 void AssertExclusiveHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700103 if (kDebugLocking) {
Ian Rogers81d425b2012-09-27 16:03:43 -0700104 CHECK(IsExclusiveHeld(self));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700105 }
106 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700107 void AssertHeld(const Thread* self) { AssertExclusiveHeld(self); }
108 void AssertHeld() { AssertExclusiveHeld(Thread::Current()); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700109
110 // Assert that the Mutex is not held by the current thread.
Ian Rogers81d425b2012-09-27 16:03:43 -0700111 void AssertNotHeldExclusive(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700112 if (kDebugLocking) {
Ian Rogers81d425b2012-09-27 16:03:43 -0700113 CHECK(!IsExclusiveHeld(self));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700114 }
115 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700116 void AssertNotHeld(const Thread* self) { AssertNotHeldExclusive(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700117
118 // Id associated with exclusive owner.
119 uint64_t GetExclusiveOwnerTid() const;
120
121 // Returns how many times this Mutex has been locked, it is better to use AssertHeld/NotHeld.
122 unsigned int GetDepth() const {
123 return recursion_count_;
124 }
Elliott Hughesaccd83d2011-10-17 14:25:58 -0700125
126 private:
Elliott Hughes8daa0922011-09-11 13:46:25 -0700127 pthread_mutex_t mutex_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700128 const bool recursive_; // Can the lock be recursively held?
129 unsigned int recursion_count_;
Elliott Hughesf1498432012-03-28 19:34:27 -0700130 friend class ConditionVariable;
Elliott Hughes3efb8412012-03-16 16:09:38 -0700131 friend class MutexTester;
Elliott Hughes8daa0922011-09-11 13:46:25 -0700132 DISALLOW_COPY_AND_ASSIGN(Mutex);
133};
134
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700135// A ReaderWriterMutex is used to achieve mutual exclusion between threads, similar to a Mutex.
136// Unlike a Mutex a ReaderWriterMutex can be used to gain exclusive (writer) or shared (reader)
137// access to what it guards. A flaw in relation to a Mutex is that it cannot be used with a
138// condition variable. A ReaderWriterMutex can be in one of three states:
139// - Free - not owned by any thread,
140// - Exclusive - owned by a single thread,
141// - Shared(n) - shared amongst n threads.
142//
143// The effect of locking and unlocking operations on the state is:
144//
145// State | ExclusiveLock | ExclusiveUnlock | SharedLock | SharedUnlock
146// ----------------------------------------------------------------------------
147// Free | Exclusive | error | SharedLock(1) | error
148// Exclusive | Block | Free | Block | error
149// Shared(n) | Block | error | SharedLock(n+1)* | Shared(n-1) or Free
150// * for large values of n the SharedLock may block.
151class LOCKABLE ReaderWriterMutex : public BaseMutex {
Elliott Hughes8daa0922011-09-11 13:46:25 -0700152 public:
Ian Rogers81d425b2012-09-27 16:03:43 -0700153 explicit ReaderWriterMutex(const char* name, LockLevel level = kDefaultMutexLevel);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700154 ~ReaderWriterMutex();
155
156 virtual bool IsReaderWriterMutex() const { return true; }
157
158 // Block until ReaderWriterMutex is free then acquire exclusive access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700159 void ExclusiveLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION();
160 void WriterLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION() { ExclusiveLock(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700161
162 // Release exclusive access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700163 void ExclusiveUnlock(Thread* self) UNLOCK_FUNCTION();
164 void WriterUnlock(Thread* self) UNLOCK_FUNCTION() { ExclusiveUnlock(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700165
166 // Block until ReaderWriterMutex is free and acquire exclusive access. Returns true on success
167 // or false if timeout is reached.
Ian Rogers66aee5c2012-08-15 17:17:47 -0700168#if HAVE_TIMED_RWLOCK
Ian Rogers81d425b2012-09-27 16:03:43 -0700169 bool ExclusiveLockWithTimeout(Thread* self, const timespec& abs_timeout)
170 EXCLUSIVE_TRYLOCK_FUNCTION(true);
Ian Rogers66aee5c2012-08-15 17:17:47 -0700171#endif
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700172
173 // Block until ReaderWriterMutex is shared or free then acquire a share on the access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700174 void SharedLock(Thread* self) SHARED_LOCK_FUNCTION();
175 void ReaderLock(Thread* self) SHARED_LOCK_FUNCTION() { SharedLock(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700176
177 // Try to acquire share of ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700178 bool SharedTryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700179
180 // Release a share of the access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700181 void SharedUnlock(Thread* self) UNLOCK_FUNCTION();
182 void ReaderUnlock(Thread* self) UNLOCK_FUNCTION() { SharedUnlock(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700183
184 // Is the current thread the exclusive holder of the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700185 bool IsExclusiveHeld(const Thread* self) const;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700186
187 // Assert the current thread has exclusive access to the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700188 void AssertExclusiveHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700189 if (kDebugLocking) {
Ian Rogers81d425b2012-09-27 16:03:43 -0700190 CHECK(IsExclusiveHeld(self));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700191 }
192 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700193 void AssertWriterHeld(const Thread* self) { AssertExclusiveHeld(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700194
195 // Assert the current thread doesn't have exclusive access to the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700196 void AssertNotExclusiveHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700197 if (kDebugLocking) {
Ian Rogers81d425b2012-09-27 16:03:43 -0700198 CHECK(!IsExclusiveHeld(self));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700199 }
200 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700201 void AssertNotWriterHeld(const Thread* self) { AssertNotExclusiveHeld(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700202
203 // Is the current thread a shared holder of the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700204 bool IsSharedHeld(const Thread* self) const;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700205
206 // Assert the current thread has shared access to the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700207 void AssertSharedHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700208 if (kDebugLocking) {
Ian Rogers81d425b2012-09-27 16:03:43 -0700209 CHECK(IsSharedHeld(self));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700210 }
211 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700212 void AssertReaderHeld(const Thread* self) { AssertSharedHeld(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700213
214 // Assert the current thread doesn't hold this ReaderWriterMutex either in shared or exclusive
215 // mode.
Ian Rogers81d425b2012-09-27 16:03:43 -0700216 void AssertNotHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700217 if (kDebugLocking) {
Ian Rogers81d425b2012-09-27 16:03:43 -0700218 CHECK(!IsSharedHeld(self));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700219 }
Elliott Hughes8daa0922011-09-11 13:46:25 -0700220 }
221
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700222 // Id associated with exclusive owner.
223 uint64_t GetExclusiveOwnerTid() const;
Elliott Hughes8daa0922011-09-11 13:46:25 -0700224
Ian Rogers81d425b2012-09-27 16:03:43 -0700225 private:
226#if ART_USE_FUTEXES
227 // -1 implies held exclusive, +ve shared held by state_ many owners.
228 volatile int32_t state_;
229 // Exclusive owner.
230 volatile uint64_t exclusive_owner_;
231 // Pending readers.
232 volatile int32_t num_pending_readers_;
233 // Pending writers.
234 volatile int32_t num_pending_writers_;
235#else
236 pthread_rwlock_t rwlock_;
237#endif
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700238 friend class MutexTester;
239 DISALLOW_COPY_AND_ASSIGN(ReaderWriterMutex);
240};
241
242// ConditionVariables allow threads to queue and sleep. Threads may then be resumed individually
243// (Signal) or all at once (Broadcast).
Elliott Hughes5f791332011-09-15 17:45:30 -0700244class ConditionVariable {
245 public:
Elliott Hughesa51a3dd2011-10-17 15:19:26 -0700246 explicit ConditionVariable(const std::string& name);
Elliott Hughes5f791332011-09-15 17:45:30 -0700247 ~ConditionVariable();
248
249 void Broadcast();
250 void Signal();
Ian Rogers81d425b2012-09-27 16:03:43 -0700251 void Wait(Thread* self, Mutex& mutex);
252 void TimedWait(Thread* self, Mutex& mutex, const timespec& ts);
Elliott Hughes5f791332011-09-15 17:45:30 -0700253
254 private:
255 pthread_cond_t cond_;
256 std::string name_;
257 DISALLOW_COPY_AND_ASSIGN(ConditionVariable);
258};
259
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700260// Scoped locker/unlocker for a regular Mutex that acquires mu upon construction and releases it
261// upon destruction.
262class SCOPED_LOCKABLE MutexLock {
263 public:
Ian Rogers81d425b2012-09-27 16:03:43 -0700264 explicit MutexLock(Thread* self, Mutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : self_(self), mu_(mu) {
265 mu_.ExclusiveLock(self_);
266 }
267
268 explicit MutexLock(Mutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : self_(Thread::Current()), mu_(mu) {
269 mu_.ExclusiveLock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700270 }
271
272 ~MutexLock() UNLOCK_FUNCTION() {
Ian Rogers81d425b2012-09-27 16:03:43 -0700273 mu_.ExclusiveUnlock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700274 }
275
276 private:
Ian Rogers81d425b2012-09-27 16:03:43 -0700277 Thread* const self_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700278 Mutex& mu_;
279 DISALLOW_COPY_AND_ASSIGN(MutexLock);
280};
281// Catch bug where variable name is omitted. "MutexLock (lock);" instead of "MutexLock mu(lock)".
282#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_declaration_missing_variable_name)
283
284// Scoped locker/unlocker for a ReaderWriterMutex that acquires read access to mu upon
285// construction and releases it upon destruction.
286class SCOPED_LOCKABLE ReaderMutexLock {
287 public:
Ian Rogers81d425b2012-09-27 16:03:43 -0700288 explicit ReaderMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
289 self_(self), mu_(mu) {
290 mu_.SharedLock(self_);
291 }
292
293 explicit ReaderMutexLock(ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
294 self_(Thread::Current()), mu_(mu) {
295 mu_.SharedLock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700296 }
297
298 ~ReaderMutexLock() UNLOCK_FUNCTION() {
Ian Rogers81d425b2012-09-27 16:03:43 -0700299 mu_.SharedUnlock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700300 }
301
302 private:
Ian Rogers81d425b2012-09-27 16:03:43 -0700303 Thread* const self_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700304 ReaderWriterMutex& mu_;
305 DISALLOW_COPY_AND_ASSIGN(ReaderMutexLock);
306};
307// Catch bug where variable name is omitted. "ReaderMutexLock (lock);" instead of
308// "ReaderMutexLock mu(lock)".
309#define ReaderMutexLock(x) COMPILE_ASSERT(0, reader_mutex_lock_declaration_missing_variable_name)
310
311// Scoped locker/unlocker for a ReaderWriterMutex that acquires write access to mu upon
312// construction and releases it upon destruction.
313class SCOPED_LOCKABLE WriterMutexLock {
314 public:
Ian Rogers81d425b2012-09-27 16:03:43 -0700315 explicit WriterMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
316 self_(self), mu_(mu) {
317 mu_.ExclusiveLock(self_);
318 }
319
320 explicit WriterMutexLock(ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
321 self_(Thread::Current()), mu_(mu) {
322 mu_.ExclusiveLock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700323 }
324
325 ~WriterMutexLock() UNLOCK_FUNCTION() {
Ian Rogers81d425b2012-09-27 16:03:43 -0700326 mu_.ExclusiveUnlock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700327 }
328
329 private:
Ian Rogers81d425b2012-09-27 16:03:43 -0700330 Thread* self_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700331 ReaderWriterMutex& mu_;
332 DISALLOW_COPY_AND_ASSIGN(WriterMutexLock);
333};
334// Catch bug where variable name is omitted. "WriterMutexLock (lock);" instead of
335// "WriterMutexLock mu(lock)".
336#define WriterMutexLock(x) COMPILE_ASSERT(0, writer_mutex_lock_declaration_missing_variable_name)
337
Elliott Hughes8daa0922011-09-11 13:46:25 -0700338} // namespace art
339
340#endif // ART_SRC_MUTEX_H_