blob: 1738870a578c8e9231bd16a008c003daced0babf [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.
Ian Rogers01ae5802012-09-28 16:14:01 -070079std::ostream& operator<<(std::ostream& os, const Mutex& mu);
Ian Rogers00f7d0e2012-07-19 15:28:27 -070080class LOCKABLE Mutex : public BaseMutex {
81 public:
Ian Rogers81d425b2012-09-27 16:03:43 -070082 explicit Mutex(const char* name, LockLevel level = kDefaultMutexLevel, bool recursive = false);
Elliott Hughes8daa0922011-09-11 13:46:25 -070083 ~Mutex();
84
Ian Rogers00f7d0e2012-07-19 15:28:27 -070085 virtual bool IsMutex() const { return true; }
Elliott Hughes8daa0922011-09-11 13:46:25 -070086
Ian Rogers00f7d0e2012-07-19 15:28:27 -070087 // Block until mutex is free then acquire exclusive access.
Ian Rogers81d425b2012-09-27 16:03:43 -070088 void ExclusiveLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION();
89 void Lock(Thread* self) EXCLUSIVE_LOCK_FUNCTION() { ExclusiveLock(self); }
Elliott Hughes8daa0922011-09-11 13:46:25 -070090
Ian Rogers00f7d0e2012-07-19 15:28:27 -070091 // Returns true if acquires exclusive access, false otherwise.
Ian Rogers81d425b2012-09-27 16:03:43 -070092 bool ExclusiveTryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true);
93 bool TryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true) { return ExclusiveTryLock(self); }
Elliott Hughes8daa0922011-09-11 13:46:25 -070094
Ian Rogers00f7d0e2012-07-19 15:28:27 -070095 // Release exclusive access.
Ian Rogers81d425b2012-09-27 16:03:43 -070096 void ExclusiveUnlock(Thread* self) UNLOCK_FUNCTION();
97 void Unlock(Thread* self) UNLOCK_FUNCTION() { ExclusiveUnlock(self); }
Elliott Hughes8daa0922011-09-11 13:46:25 -070098
Ian Rogers00f7d0e2012-07-19 15:28:27 -070099 // Is the current thread the exclusive holder of the Mutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700100 bool IsExclusiveHeld(const Thread* self) const;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700101
102 // Assert that the Mutex is exclusively held by the current thread.
Ian Rogers81d425b2012-09-27 16:03:43 -0700103 void AssertExclusiveHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700104 if (kDebugLocking) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700105 CHECK(IsExclusiveHeld(self)) << *this;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700106 }
107 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700108 void AssertHeld(const Thread* self) { AssertExclusiveHeld(self); }
109 void AssertHeld() { AssertExclusiveHeld(Thread::Current()); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700110
111 // Assert that the Mutex is not held by the current thread.
Ian Rogers81d425b2012-09-27 16:03:43 -0700112 void AssertNotHeldExclusive(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700113 if (kDebugLocking) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700114 CHECK(!IsExclusiveHeld(self)) << *this;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700115 }
116 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700117 void AssertNotHeld(const Thread* self) { AssertNotHeldExclusive(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700118
119 // Id associated with exclusive owner.
120 uint64_t GetExclusiveOwnerTid() const;
121
122 // Returns how many times this Mutex has been locked, it is better to use AssertHeld/NotHeld.
123 unsigned int GetDepth() const {
124 return recursion_count_;
125 }
Elliott Hughesaccd83d2011-10-17 14:25:58 -0700126
Ian Rogers01ae5802012-09-28 16:14:01 -0700127 std::string Dump() const;
128
Elliott Hughesaccd83d2011-10-17 14:25:58 -0700129 private:
Elliott Hughes8daa0922011-09-11 13:46:25 -0700130 pthread_mutex_t mutex_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700131 const bool recursive_; // Can the lock be recursively held?
132 unsigned int recursion_count_;
Elliott Hughesf1498432012-03-28 19:34:27 -0700133 friend class ConditionVariable;
Elliott Hughes3efb8412012-03-16 16:09:38 -0700134 friend class MutexTester;
Elliott Hughes8daa0922011-09-11 13:46:25 -0700135 DISALLOW_COPY_AND_ASSIGN(Mutex);
136};
137
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700138// A ReaderWriterMutex is used to achieve mutual exclusion between threads, similar to a Mutex.
139// Unlike a Mutex a ReaderWriterMutex can be used to gain exclusive (writer) or shared (reader)
140// access to what it guards. A flaw in relation to a Mutex is that it cannot be used with a
141// condition variable. A ReaderWriterMutex can be in one of three states:
142// - Free - not owned by any thread,
143// - Exclusive - owned by a single thread,
144// - Shared(n) - shared amongst n threads.
145//
146// The effect of locking and unlocking operations on the state is:
147//
148// State | ExclusiveLock | ExclusiveUnlock | SharedLock | SharedUnlock
149// ----------------------------------------------------------------------------
150// Free | Exclusive | error | SharedLock(1) | error
151// Exclusive | Block | Free | Block | error
152// Shared(n) | Block | error | SharedLock(n+1)* | Shared(n-1) or Free
153// * for large values of n the SharedLock may block.
Ian Rogers01ae5802012-09-28 16:14:01 -0700154std::ostream& operator<<(std::ostream& os, const ReaderWriterMutex& mu);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700155class LOCKABLE ReaderWriterMutex : public BaseMutex {
Elliott Hughes8daa0922011-09-11 13:46:25 -0700156 public:
Ian Rogers81d425b2012-09-27 16:03:43 -0700157 explicit ReaderWriterMutex(const char* name, LockLevel level = kDefaultMutexLevel);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700158 ~ReaderWriterMutex();
159
160 virtual bool IsReaderWriterMutex() const { return true; }
161
162 // Block until ReaderWriterMutex is free then acquire exclusive access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700163 void ExclusiveLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION();
164 void WriterLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION() { ExclusiveLock(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700165
166 // Release exclusive access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700167 void ExclusiveUnlock(Thread* self) UNLOCK_FUNCTION();
168 void WriterUnlock(Thread* self) UNLOCK_FUNCTION() { ExclusiveUnlock(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700169
170 // Block until ReaderWriterMutex is free and acquire exclusive access. Returns true on success
171 // or false if timeout is reached.
Ian Rogers66aee5c2012-08-15 17:17:47 -0700172#if HAVE_TIMED_RWLOCK
Ian Rogers81d425b2012-09-27 16:03:43 -0700173 bool ExclusiveLockWithTimeout(Thread* self, const timespec& abs_timeout)
174 EXCLUSIVE_TRYLOCK_FUNCTION(true);
Ian Rogers66aee5c2012-08-15 17:17:47 -0700175#endif
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700176
177 // Block until ReaderWriterMutex is shared or free then acquire a share on the access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700178 void SharedLock(Thread* self) SHARED_LOCK_FUNCTION();
179 void ReaderLock(Thread* self) SHARED_LOCK_FUNCTION() { SharedLock(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700180
181 // Try to acquire share of ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700182 bool SharedTryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700183
184 // Release a share of the access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700185 void SharedUnlock(Thread* self) UNLOCK_FUNCTION();
186 void ReaderUnlock(Thread* self) UNLOCK_FUNCTION() { SharedUnlock(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700187
188 // Is the current thread the exclusive holder of the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700189 bool IsExclusiveHeld(const Thread* self) const;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700190
191 // Assert the current thread has exclusive access to the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700192 void AssertExclusiveHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700193 if (kDebugLocking) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700194 CHECK(IsExclusiveHeld(self)) << *this;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700195 }
196 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700197 void AssertWriterHeld(const Thread* self) { AssertExclusiveHeld(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700198
199 // Assert the current thread doesn't have exclusive access to the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700200 void AssertNotExclusiveHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700201 if (kDebugLocking) {
Ian Rogers81d425b2012-09-27 16:03:43 -0700202 CHECK(!IsExclusiveHeld(self));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700203 }
204 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700205 void AssertNotWriterHeld(const Thread* self) { AssertNotExclusiveHeld(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700206
207 // Is the current thread a shared holder of the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700208 bool IsSharedHeld(const Thread* self) const;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700209
210 // Assert the current thread has shared access to the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700211 void AssertSharedHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700212 if (kDebugLocking) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700213 CHECK(IsSharedHeld(self)) << *this;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700214 }
215 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700216 void AssertReaderHeld(const Thread* self) { AssertSharedHeld(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700217
218 // Assert the current thread doesn't hold this ReaderWriterMutex either in shared or exclusive
219 // mode.
Ian Rogers81d425b2012-09-27 16:03:43 -0700220 void AssertNotHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700221 if (kDebugLocking) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700222 CHECK(!IsSharedHeld(self)) << *this;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700223 }
Elliott Hughes8daa0922011-09-11 13:46:25 -0700224 }
225
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700226 // Id associated with exclusive owner.
227 uint64_t GetExclusiveOwnerTid() const;
Elliott Hughes8daa0922011-09-11 13:46:25 -0700228
Ian Rogers01ae5802012-09-28 16:14:01 -0700229 std::string Dump() const;
230
Ian Rogers81d425b2012-09-27 16:03:43 -0700231 private:
232#if ART_USE_FUTEXES
233 // -1 implies held exclusive, +ve shared held by state_ many owners.
234 volatile int32_t state_;
235 // Exclusive owner.
236 volatile uint64_t exclusive_owner_;
237 // Pending readers.
238 volatile int32_t num_pending_readers_;
239 // Pending writers.
240 volatile int32_t num_pending_writers_;
241#else
242 pthread_rwlock_t rwlock_;
243#endif
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700244 friend class MutexTester;
245 DISALLOW_COPY_AND_ASSIGN(ReaderWriterMutex);
246};
247
248// ConditionVariables allow threads to queue and sleep. Threads may then be resumed individually
249// (Signal) or all at once (Broadcast).
Elliott Hughes5f791332011-09-15 17:45:30 -0700250class ConditionVariable {
251 public:
Elliott Hughesa51a3dd2011-10-17 15:19:26 -0700252 explicit ConditionVariable(const std::string& name);
Elliott Hughes5f791332011-09-15 17:45:30 -0700253 ~ConditionVariable();
254
255 void Broadcast();
256 void Signal();
Ian Rogers81d425b2012-09-27 16:03:43 -0700257 void Wait(Thread* self, Mutex& mutex);
258 void TimedWait(Thread* self, Mutex& mutex, const timespec& ts);
Elliott Hughes5f791332011-09-15 17:45:30 -0700259
260 private:
261 pthread_cond_t cond_;
262 std::string name_;
263 DISALLOW_COPY_AND_ASSIGN(ConditionVariable);
264};
265
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700266// Scoped locker/unlocker for a regular Mutex that acquires mu upon construction and releases it
267// upon destruction.
268class SCOPED_LOCKABLE MutexLock {
269 public:
Ian Rogers81d425b2012-09-27 16:03:43 -0700270 explicit MutexLock(Thread* self, Mutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : self_(self), mu_(mu) {
271 mu_.ExclusiveLock(self_);
272 }
273
274 explicit MutexLock(Mutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : self_(Thread::Current()), mu_(mu) {
275 mu_.ExclusiveLock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700276 }
277
278 ~MutexLock() UNLOCK_FUNCTION() {
Ian Rogers81d425b2012-09-27 16:03:43 -0700279 mu_.ExclusiveUnlock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700280 }
281
282 private:
Ian Rogers81d425b2012-09-27 16:03:43 -0700283 Thread* const self_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700284 Mutex& mu_;
285 DISALLOW_COPY_AND_ASSIGN(MutexLock);
286};
287// Catch bug where variable name is omitted. "MutexLock (lock);" instead of "MutexLock mu(lock)".
288#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_declaration_missing_variable_name)
289
290// Scoped locker/unlocker for a ReaderWriterMutex that acquires read access to mu upon
291// construction and releases it upon destruction.
292class SCOPED_LOCKABLE ReaderMutexLock {
293 public:
Ian Rogers81d425b2012-09-27 16:03:43 -0700294 explicit ReaderMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
295 self_(self), mu_(mu) {
296 mu_.SharedLock(self_);
297 }
298
299 explicit ReaderMutexLock(ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
300 self_(Thread::Current()), mu_(mu) {
301 mu_.SharedLock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700302 }
303
304 ~ReaderMutexLock() UNLOCK_FUNCTION() {
Ian Rogers81d425b2012-09-27 16:03:43 -0700305 mu_.SharedUnlock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700306 }
307
308 private:
Ian Rogers81d425b2012-09-27 16:03:43 -0700309 Thread* const self_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700310 ReaderWriterMutex& mu_;
311 DISALLOW_COPY_AND_ASSIGN(ReaderMutexLock);
312};
313// Catch bug where variable name is omitted. "ReaderMutexLock (lock);" instead of
314// "ReaderMutexLock mu(lock)".
315#define ReaderMutexLock(x) COMPILE_ASSERT(0, reader_mutex_lock_declaration_missing_variable_name)
316
317// Scoped locker/unlocker for a ReaderWriterMutex that acquires write access to mu upon
318// construction and releases it upon destruction.
319class SCOPED_LOCKABLE WriterMutexLock {
320 public:
Ian Rogers81d425b2012-09-27 16:03:43 -0700321 explicit WriterMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
322 self_(self), mu_(mu) {
323 mu_.ExclusiveLock(self_);
324 }
325
326 explicit WriterMutexLock(ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
327 self_(Thread::Current()), mu_(mu) {
328 mu_.ExclusiveLock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700329 }
330
331 ~WriterMutexLock() UNLOCK_FUNCTION() {
Ian Rogers81d425b2012-09-27 16:03:43 -0700332 mu_.ExclusiveUnlock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700333 }
334
335 private:
Ian Rogers81d425b2012-09-27 16:03:43 -0700336 Thread* self_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700337 ReaderWriterMutex& mu_;
338 DISALLOW_COPY_AND_ASSIGN(WriterMutexLock);
339};
340// Catch bug where variable name is omitted. "WriterMutexLock (lock);" instead of
341// "WriterMutexLock mu(lock)".
342#define WriterMutexLock(x) COMPILE_ASSERT(0, writer_mutex_lock_declaration_missing_variable_name)
343
Elliott Hughes8daa0922011-09-11 13:46:25 -0700344} // namespace art
345
346#endif // ART_SRC_MUTEX_H_