blob: f69eb32dbc575ef0c705595e94eeaad9d10da2e5 [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
Ian Rogersab470162012-09-29 23:06:53 -070031#if defined(__APPLE__)
Ian Rogers81d425b2012-09-27 16:03:43 -070032#define ART_USE_FUTEXES 0
Ian Rogersab470162012-09-29 23:06:53 -070033#else
34#define ART_USE_FUTEXES 1
35#endif
Elliott Hughes8daa0922011-09-11 13:46:25 -070036
Ian Rogers66aee5c2012-08-15 17:17:47 -070037// Currently Darwin doesn't support locks with timeouts.
38#if !defined(__APPLE__)
39#define HAVE_TIMED_RWLOCK 1
40#else
41#define HAVE_TIMED_RWLOCK 0
42#endif
43
Elliott Hughes8daa0922011-09-11 13:46:25 -070044namespace art {
45
Ian Rogers25fd14b2012-09-05 10:56:38 -070046const bool kDebugLocking = kIsDebugBuild;
47
Ian Rogers00f7d0e2012-07-19 15:28:27 -070048// Base class for all Mutex implementations
49class BaseMutex {
50 public:
51 const std::string& GetName() const {
52 return name_;
53 }
54
55 virtual bool IsMutex() const { return false; }
56 virtual bool IsReaderWriterMutex() const { return false; }
57
58 protected:
59 friend class ConditionVariable;
60
Ian Rogers81d425b2012-09-27 16:03:43 -070061 BaseMutex(const char* name, LockLevel level);
Ian Rogers00f7d0e2012-07-19 15:28:27 -070062 virtual ~BaseMutex() {}
Ian Rogers81d425b2012-09-27 16:03:43 -070063 void RegisterAsLocked(Thread* self);
64 void RegisterAsUnlocked(Thread* self);
65 void CheckSafeToWait(Thread* self);
Ian Rogers00f7d0e2012-07-19 15:28:27 -070066
Ian Rogers81d425b2012-09-27 16:03:43 -070067 const LockLevel level_; // Support for lock hierarchy.
Ian Rogers00f7d0e2012-07-19 15:28:27 -070068 const std::string name_;
69};
70
71// A Mutex is used to achieve mutual exclusion between threads. A Mutex can be used to gain
72// exclusive access to what it guards. A Mutex can be in one of two states:
73// - Free - not owned by any thread,
74// - Exclusive - owned by a single thread.
75//
76// The effect of locking and unlocking operations on the state is:
77// State | ExclusiveLock | ExclusiveUnlock
78// -------------------------------------------
79// Free | Exclusive | error
80// Exclusive | Block* | Free
81// * Mutex is not reentrant and so an attempt to ExclusiveLock on the same thread will result in
82// an error. Being non-reentrant simplifies Waiting on ConditionVariables.
Ian Rogers01ae5802012-09-28 16:14:01 -070083std::ostream& operator<<(std::ostream& os, const Mutex& mu);
Ian Rogers00f7d0e2012-07-19 15:28:27 -070084class LOCKABLE Mutex : public BaseMutex {
85 public:
Ian Rogers81d425b2012-09-27 16:03:43 -070086 explicit Mutex(const char* name, LockLevel level = kDefaultMutexLevel, bool recursive = false);
Elliott Hughes8daa0922011-09-11 13:46:25 -070087 ~Mutex();
88
Ian Rogers00f7d0e2012-07-19 15:28:27 -070089 virtual bool IsMutex() const { return true; }
Elliott Hughes8daa0922011-09-11 13:46:25 -070090
Ian Rogers00f7d0e2012-07-19 15:28:27 -070091 // Block until mutex is free then acquire exclusive access.
Ian Rogers81d425b2012-09-27 16:03:43 -070092 void ExclusiveLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION();
93 void Lock(Thread* self) EXCLUSIVE_LOCK_FUNCTION() { ExclusiveLock(self); }
Elliott Hughes8daa0922011-09-11 13:46:25 -070094
Ian Rogers00f7d0e2012-07-19 15:28:27 -070095 // Returns true if acquires exclusive access, false otherwise.
Ian Rogers81d425b2012-09-27 16:03:43 -070096 bool ExclusiveTryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true);
97 bool TryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true) { return ExclusiveTryLock(self); }
Elliott Hughes8daa0922011-09-11 13:46:25 -070098
Ian Rogers00f7d0e2012-07-19 15:28:27 -070099 // Release exclusive access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700100 void ExclusiveUnlock(Thread* self) UNLOCK_FUNCTION();
101 void Unlock(Thread* self) UNLOCK_FUNCTION() { ExclusiveUnlock(self); }
Elliott Hughes8daa0922011-09-11 13:46:25 -0700102
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700103 // Is the current thread the exclusive holder of the Mutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700104 bool IsExclusiveHeld(const Thread* self) const;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700105
106 // Assert that the Mutex is exclusively held by the current thread.
Ian Rogers81d425b2012-09-27 16:03:43 -0700107 void AssertExclusiveHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700108 if (kDebugLocking) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700109 CHECK(IsExclusiveHeld(self)) << *this;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700110 }
111 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700112 void AssertHeld(const Thread* self) { AssertExclusiveHeld(self); }
113 void AssertHeld() { AssertExclusiveHeld(Thread::Current()); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700114
115 // Assert that the Mutex is not held by the current thread.
Ian Rogers81d425b2012-09-27 16:03:43 -0700116 void AssertNotHeldExclusive(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700117 if (kDebugLocking) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700118 CHECK(!IsExclusiveHeld(self)) << *this;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700119 }
120 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700121 void AssertNotHeld(const Thread* self) { AssertNotHeldExclusive(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700122
123 // Id associated with exclusive owner.
124 uint64_t GetExclusiveOwnerTid() const;
125
126 // Returns how many times this Mutex has been locked, it is better to use AssertHeld/NotHeld.
127 unsigned int GetDepth() const {
128 return recursion_count_;
129 }
Elliott Hughesaccd83d2011-10-17 14:25:58 -0700130
Ian Rogers01ae5802012-09-28 16:14:01 -0700131 std::string Dump() const;
132
Elliott Hughesaccd83d2011-10-17 14:25:58 -0700133 private:
Elliott Hughes8daa0922011-09-11 13:46:25 -0700134 pthread_mutex_t mutex_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700135 const bool recursive_; // Can the lock be recursively held?
136 unsigned int recursion_count_;
Elliott Hughesf1498432012-03-28 19:34:27 -0700137 friend class ConditionVariable;
Elliott Hughes3efb8412012-03-16 16:09:38 -0700138 friend class MutexTester;
Elliott Hughes8daa0922011-09-11 13:46:25 -0700139 DISALLOW_COPY_AND_ASSIGN(Mutex);
140};
141
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700142// A ReaderWriterMutex is used to achieve mutual exclusion between threads, similar to a Mutex.
143// Unlike a Mutex a ReaderWriterMutex can be used to gain exclusive (writer) or shared (reader)
144// access to what it guards. A flaw in relation to a Mutex is that it cannot be used with a
145// condition variable. A ReaderWriterMutex can be in one of three states:
146// - Free - not owned by any thread,
147// - Exclusive - owned by a single thread,
148// - Shared(n) - shared amongst n threads.
149//
150// The effect of locking and unlocking operations on the state is:
151//
152// State | ExclusiveLock | ExclusiveUnlock | SharedLock | SharedUnlock
153// ----------------------------------------------------------------------------
154// Free | Exclusive | error | SharedLock(1) | error
155// Exclusive | Block | Free | Block | error
156// Shared(n) | Block | error | SharedLock(n+1)* | Shared(n-1) or Free
157// * for large values of n the SharedLock may block.
Ian Rogers01ae5802012-09-28 16:14:01 -0700158std::ostream& operator<<(std::ostream& os, const ReaderWriterMutex& mu);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700159class LOCKABLE ReaderWriterMutex : public BaseMutex {
Elliott Hughes8daa0922011-09-11 13:46:25 -0700160 public:
Ian Rogers81d425b2012-09-27 16:03:43 -0700161 explicit ReaderWriterMutex(const char* name, LockLevel level = kDefaultMutexLevel);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700162 ~ReaderWriterMutex();
163
164 virtual bool IsReaderWriterMutex() const { return true; }
165
166 // Block until ReaderWriterMutex is free then acquire exclusive access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700167 void ExclusiveLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION();
168 void WriterLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION() { ExclusiveLock(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700169
170 // Release exclusive access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700171 void ExclusiveUnlock(Thread* self) UNLOCK_FUNCTION();
172 void WriterUnlock(Thread* self) UNLOCK_FUNCTION() { ExclusiveUnlock(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700173
174 // Block until ReaderWriterMutex is free and acquire exclusive access. Returns true on success
175 // or false if timeout is reached.
Ian Rogers66aee5c2012-08-15 17:17:47 -0700176#if HAVE_TIMED_RWLOCK
Ian Rogers81d425b2012-09-27 16:03:43 -0700177 bool ExclusiveLockWithTimeout(Thread* self, const timespec& abs_timeout)
178 EXCLUSIVE_TRYLOCK_FUNCTION(true);
Ian Rogers66aee5c2012-08-15 17:17:47 -0700179#endif
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700180
181 // Block until ReaderWriterMutex is shared or free then acquire a share on the access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700182 void SharedLock(Thread* self) SHARED_LOCK_FUNCTION();
183 void ReaderLock(Thread* self) SHARED_LOCK_FUNCTION() { SharedLock(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700184
185 // Try to acquire share of ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700186 bool SharedTryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700187
188 // Release a share of the access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700189 void SharedUnlock(Thread* self) UNLOCK_FUNCTION();
190 void ReaderUnlock(Thread* self) UNLOCK_FUNCTION() { SharedUnlock(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700191
192 // Is the current thread the exclusive holder of the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700193 bool IsExclusiveHeld(const Thread* self) const;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700194
195 // Assert the current thread has exclusive access to the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700196 void AssertExclusiveHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700197 if (kDebugLocking) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700198 CHECK(IsExclusiveHeld(self)) << *this;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700199 }
200 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700201 void AssertWriterHeld(const Thread* self) { AssertExclusiveHeld(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700202
203 // Assert the current thread doesn't have exclusive access to the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700204 void AssertNotExclusiveHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700205 if (kDebugLocking) {
Ian Rogers81d425b2012-09-27 16:03:43 -0700206 CHECK(!IsExclusiveHeld(self));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700207 }
208 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700209 void AssertNotWriterHeld(const Thread* self) { AssertNotExclusiveHeld(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700210
211 // Is the current thread a shared holder of the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700212 bool IsSharedHeld(const Thread* self) const;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700213
214 // Assert the current thread has shared access to the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700215 void AssertSharedHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700216 if (kDebugLocking) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700217 CHECK(IsSharedHeld(self)) << *this;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700218 }
219 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700220 void AssertReaderHeld(const Thread* self) { AssertSharedHeld(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700221
222 // Assert the current thread doesn't hold this ReaderWriterMutex either in shared or exclusive
223 // mode.
Ian Rogers81d425b2012-09-27 16:03:43 -0700224 void AssertNotHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700225 if (kDebugLocking) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700226 CHECK(!IsSharedHeld(self)) << *this;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700227 }
Elliott Hughes8daa0922011-09-11 13:46:25 -0700228 }
229
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700230 // Id associated with exclusive owner.
231 uint64_t GetExclusiveOwnerTid() const;
Elliott Hughes8daa0922011-09-11 13:46:25 -0700232
Ian Rogers01ae5802012-09-28 16:14:01 -0700233 std::string Dump() const;
234
Ian Rogers81d425b2012-09-27 16:03:43 -0700235 private:
236#if ART_USE_FUTEXES
237 // -1 implies held exclusive, +ve shared held by state_ many owners.
238 volatile int32_t state_;
239 // Exclusive owner.
240 volatile uint64_t exclusive_owner_;
241 // Pending readers.
242 volatile int32_t num_pending_readers_;
243 // Pending writers.
244 volatile int32_t num_pending_writers_;
245#else
246 pthread_rwlock_t rwlock_;
247#endif
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700248 friend class MutexTester;
249 DISALLOW_COPY_AND_ASSIGN(ReaderWriterMutex);
250};
251
252// ConditionVariables allow threads to queue and sleep. Threads may then be resumed individually
253// (Signal) or all at once (Broadcast).
Elliott Hughes5f791332011-09-15 17:45:30 -0700254class ConditionVariable {
255 public:
Elliott Hughesa51a3dd2011-10-17 15:19:26 -0700256 explicit ConditionVariable(const std::string& name);
Elliott Hughes5f791332011-09-15 17:45:30 -0700257 ~ConditionVariable();
258
259 void Broadcast();
260 void Signal();
Ian Rogers81d425b2012-09-27 16:03:43 -0700261 void Wait(Thread* self, Mutex& mutex);
262 void TimedWait(Thread* self, Mutex& mutex, const timespec& ts);
Elliott Hughes5f791332011-09-15 17:45:30 -0700263
264 private:
265 pthread_cond_t cond_;
266 std::string name_;
267 DISALLOW_COPY_AND_ASSIGN(ConditionVariable);
268};
269
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700270// Scoped locker/unlocker for a regular Mutex that acquires mu upon construction and releases it
271// upon destruction.
272class SCOPED_LOCKABLE MutexLock {
273 public:
Ian Rogers81d425b2012-09-27 16:03:43 -0700274 explicit MutexLock(Thread* self, Mutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : self_(self), mu_(mu) {
275 mu_.ExclusiveLock(self_);
276 }
277
278 explicit MutexLock(Mutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : self_(Thread::Current()), mu_(mu) {
279 mu_.ExclusiveLock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700280 }
281
282 ~MutexLock() UNLOCK_FUNCTION() {
Ian Rogers81d425b2012-09-27 16:03:43 -0700283 mu_.ExclusiveUnlock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700284 }
285
286 private:
Ian Rogers81d425b2012-09-27 16:03:43 -0700287 Thread* const self_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700288 Mutex& mu_;
289 DISALLOW_COPY_AND_ASSIGN(MutexLock);
290};
291// Catch bug where variable name is omitted. "MutexLock (lock);" instead of "MutexLock mu(lock)".
292#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_declaration_missing_variable_name)
293
294// Scoped locker/unlocker for a ReaderWriterMutex that acquires read access to mu upon
295// construction and releases it upon destruction.
296class SCOPED_LOCKABLE ReaderMutexLock {
297 public:
Ian Rogers81d425b2012-09-27 16:03:43 -0700298 explicit ReaderMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
299 self_(self), mu_(mu) {
300 mu_.SharedLock(self_);
301 }
302
303 explicit ReaderMutexLock(ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
304 self_(Thread::Current()), mu_(mu) {
305 mu_.SharedLock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700306 }
307
308 ~ReaderMutexLock() UNLOCK_FUNCTION() {
Ian Rogers81d425b2012-09-27 16:03:43 -0700309 mu_.SharedUnlock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700310 }
311
312 private:
Ian Rogers81d425b2012-09-27 16:03:43 -0700313 Thread* const self_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700314 ReaderWriterMutex& mu_;
315 DISALLOW_COPY_AND_ASSIGN(ReaderMutexLock);
316};
317// Catch bug where variable name is omitted. "ReaderMutexLock (lock);" instead of
318// "ReaderMutexLock mu(lock)".
319#define ReaderMutexLock(x) COMPILE_ASSERT(0, reader_mutex_lock_declaration_missing_variable_name)
320
321// Scoped locker/unlocker for a ReaderWriterMutex that acquires write access to mu upon
322// construction and releases it upon destruction.
323class SCOPED_LOCKABLE WriterMutexLock {
324 public:
Ian Rogers81d425b2012-09-27 16:03:43 -0700325 explicit WriterMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
326 self_(self), mu_(mu) {
327 mu_.ExclusiveLock(self_);
328 }
329
330 explicit WriterMutexLock(ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
331 self_(Thread::Current()), mu_(mu) {
332 mu_.ExclusiveLock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700333 }
334
335 ~WriterMutexLock() UNLOCK_FUNCTION() {
Ian Rogers81d425b2012-09-27 16:03:43 -0700336 mu_.ExclusiveUnlock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700337 }
338
339 private:
Ian Rogers81d425b2012-09-27 16:03:43 -0700340 Thread* self_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700341 ReaderWriterMutex& mu_;
342 DISALLOW_COPY_AND_ASSIGN(WriterMutexLock);
343};
344// Catch bug where variable name is omitted. "WriterMutexLock (lock);" instead of
345// "WriterMutexLock mu(lock)".
346#define WriterMutexLock(x) COMPILE_ASSERT(0, writer_mutex_lock_declaration_missing_variable_name)
347
Elliott Hughes8daa0922011-09-11 13:46:25 -0700348} // namespace art
349
350#endif // ART_SRC_MUTEX_H_