blob: d51e2ccb2d543ee7076892d152a596670f18233a [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"
Ian Rogers50b35e22012-10-04 10:09:15 -070028#include "logging.h"
Elliott Hughes8daa0922011-09-11 13:46:25 -070029#include "macros.h"
Ian Rogers81d425b2012-09-27 16:03:43 -070030
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
Ian Rogers369809b2012-09-30 22:28:55 -070034#define ART_USE_FUTEXES 0
Ian Rogersab470162012-09-29 23:06:53 -070035#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 Rogers50b35e22012-10-04 10:09:15 -070046class Thread;
47
Ian Rogers25fd14b2012-09-05 10:56:38 -070048const bool kDebugLocking = kIsDebugBuild;
49
Ian Rogers00f7d0e2012-07-19 15:28:27 -070050// Base class for all Mutex implementations
51class BaseMutex {
52 public:
53 const std::string& GetName() const {
54 return name_;
55 }
56
57 virtual bool IsMutex() const { return false; }
58 virtual bool IsReaderWriterMutex() const { return false; }
59
60 protected:
61 friend class ConditionVariable;
62
Ian Rogers81d425b2012-09-27 16:03:43 -070063 BaseMutex(const char* name, LockLevel level);
Ian Rogers00f7d0e2012-07-19 15:28:27 -070064 virtual ~BaseMutex() {}
Ian Rogers81d425b2012-09-27 16:03:43 -070065 void RegisterAsLocked(Thread* self);
66 void RegisterAsUnlocked(Thread* self);
67 void CheckSafeToWait(Thread* self);
Ian Rogers00f7d0e2012-07-19 15:28:27 -070068
Ian Rogers81d425b2012-09-27 16:03:43 -070069 const LockLevel level_; // Support for lock hierarchy.
Ian Rogers00f7d0e2012-07-19 15:28:27 -070070 const std::string name_;
71};
72
73// A Mutex is used to achieve mutual exclusion between threads. A Mutex can be used to gain
74// exclusive access to what it guards. A Mutex can be in one of two states:
75// - Free - not owned by any thread,
76// - Exclusive - owned by a single thread.
77//
78// The effect of locking and unlocking operations on the state is:
79// State | ExclusiveLock | ExclusiveUnlock
80// -------------------------------------------
81// Free | Exclusive | error
82// Exclusive | Block* | Free
83// * Mutex is not reentrant and so an attempt to ExclusiveLock on the same thread will result in
84// an error. Being non-reentrant simplifies Waiting on ConditionVariables.
Ian Rogers01ae5802012-09-28 16:14:01 -070085std::ostream& operator<<(std::ostream& os, const Mutex& mu);
Ian Rogers00f7d0e2012-07-19 15:28:27 -070086class LOCKABLE Mutex : public BaseMutex {
87 public:
Ian Rogers81d425b2012-09-27 16:03:43 -070088 explicit Mutex(const char* name, LockLevel level = kDefaultMutexLevel, bool recursive = false);
Elliott Hughes8daa0922011-09-11 13:46:25 -070089 ~Mutex();
90
Ian Rogers00f7d0e2012-07-19 15:28:27 -070091 virtual bool IsMutex() const { return true; }
Elliott Hughes8daa0922011-09-11 13:46:25 -070092
Ian Rogers00f7d0e2012-07-19 15:28:27 -070093 // Block until mutex is free then acquire exclusive access.
Ian Rogers81d425b2012-09-27 16:03:43 -070094 void ExclusiveLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION();
95 void Lock(Thread* self) EXCLUSIVE_LOCK_FUNCTION() { ExclusiveLock(self); }
Elliott Hughes8daa0922011-09-11 13:46:25 -070096
Ian Rogers00f7d0e2012-07-19 15:28:27 -070097 // Returns true if acquires exclusive access, false otherwise.
Ian Rogers81d425b2012-09-27 16:03:43 -070098 bool ExclusiveTryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true);
99 bool TryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true) { return ExclusiveTryLock(self); }
Elliott Hughes8daa0922011-09-11 13:46:25 -0700100
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700101 // Release exclusive access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700102 void ExclusiveUnlock(Thread* self) UNLOCK_FUNCTION();
103 void Unlock(Thread* self) UNLOCK_FUNCTION() { ExclusiveUnlock(self); }
Elliott Hughes8daa0922011-09-11 13:46:25 -0700104
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700105 // Is the current thread the exclusive holder of the Mutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700106 bool IsExclusiveHeld(const Thread* self) const;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700107
108 // Assert that the Mutex is exclusively held by the current thread.
Ian Rogers81d425b2012-09-27 16:03:43 -0700109 void AssertExclusiveHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700110 if (kDebugLocking) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700111 CHECK(IsExclusiveHeld(self)) << *this;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700112 }
113 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700114 void AssertHeld(const Thread* self) { AssertExclusiveHeld(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700115
116 // Assert that the Mutex is not held by the current thread.
Ian Rogers81d425b2012-09-27 16:03:43 -0700117 void AssertNotHeldExclusive(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700118 if (kDebugLocking) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700119 CHECK(!IsExclusiveHeld(self)) << *this;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700120 }
121 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700122 void AssertNotHeld(const Thread* self) { AssertNotHeldExclusive(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700123
124 // Id associated with exclusive owner.
125 uint64_t GetExclusiveOwnerTid() const;
126
127 // Returns how many times this Mutex has been locked, it is better to use AssertHeld/NotHeld.
128 unsigned int GetDepth() const {
129 return recursion_count_;
130 }
Elliott Hughesaccd83d2011-10-17 14:25:58 -0700131
Ian Rogers01ae5802012-09-28 16:14:01 -0700132 std::string Dump() const;
133
Elliott Hughesaccd83d2011-10-17 14:25:58 -0700134 private:
Elliott Hughes8daa0922011-09-11 13:46:25 -0700135 pthread_mutex_t mutex_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700136 const bool recursive_; // Can the lock be recursively held?
137 unsigned int recursion_count_;
Elliott Hughesf1498432012-03-28 19:34:27 -0700138 friend class ConditionVariable;
Elliott Hughes3efb8412012-03-16 16:09:38 -0700139 friend class MutexTester;
Elliott Hughes8daa0922011-09-11 13:46:25 -0700140 DISALLOW_COPY_AND_ASSIGN(Mutex);
141};
142
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700143// A ReaderWriterMutex is used to achieve mutual exclusion between threads, similar to a Mutex.
144// Unlike a Mutex a ReaderWriterMutex can be used to gain exclusive (writer) or shared (reader)
145// access to what it guards. A flaw in relation to a Mutex is that it cannot be used with a
146// condition variable. A ReaderWriterMutex can be in one of three states:
147// - Free - not owned by any thread,
148// - Exclusive - owned by a single thread,
149// - Shared(n) - shared amongst n threads.
150//
151// The effect of locking and unlocking operations on the state is:
152//
153// State | ExclusiveLock | ExclusiveUnlock | SharedLock | SharedUnlock
154// ----------------------------------------------------------------------------
155// Free | Exclusive | error | SharedLock(1) | error
156// Exclusive | Block | Free | Block | error
157// Shared(n) | Block | error | SharedLock(n+1)* | Shared(n-1) or Free
158// * for large values of n the SharedLock may block.
Ian Rogers01ae5802012-09-28 16:14:01 -0700159std::ostream& operator<<(std::ostream& os, const ReaderWriterMutex& mu);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700160class LOCKABLE ReaderWriterMutex : public BaseMutex {
Elliott Hughes8daa0922011-09-11 13:46:25 -0700161 public:
Ian Rogers81d425b2012-09-27 16:03:43 -0700162 explicit ReaderWriterMutex(const char* name, LockLevel level = kDefaultMutexLevel);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700163 ~ReaderWriterMutex();
164
165 virtual bool IsReaderWriterMutex() const { return true; }
166
167 // Block until ReaderWriterMutex is free then acquire exclusive access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700168 void ExclusiveLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION();
169 void WriterLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION() { ExclusiveLock(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700170
171 // Release exclusive access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700172 void ExclusiveUnlock(Thread* self) UNLOCK_FUNCTION();
173 void WriterUnlock(Thread* self) UNLOCK_FUNCTION() { ExclusiveUnlock(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700174
175 // Block until ReaderWriterMutex is free and acquire exclusive access. Returns true on success
176 // or false if timeout is reached.
Ian Rogers66aee5c2012-08-15 17:17:47 -0700177#if HAVE_TIMED_RWLOCK
Ian Rogers81d425b2012-09-27 16:03:43 -0700178 bool ExclusiveLockWithTimeout(Thread* self, const timespec& abs_timeout)
179 EXCLUSIVE_TRYLOCK_FUNCTION(true);
Ian Rogers66aee5c2012-08-15 17:17:47 -0700180#endif
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700181
182 // Block until ReaderWriterMutex is shared or free then acquire a share on the access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700183 void SharedLock(Thread* self) SHARED_LOCK_FUNCTION();
184 void ReaderLock(Thread* self) SHARED_LOCK_FUNCTION() { SharedLock(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700185
186 // Try to acquire share of ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700187 bool SharedTryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700188
189 // Release a share of the access.
Ian Rogers81d425b2012-09-27 16:03:43 -0700190 void SharedUnlock(Thread* self) UNLOCK_FUNCTION();
191 void ReaderUnlock(Thread* self) UNLOCK_FUNCTION() { SharedUnlock(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700192
193 // Is the current thread the exclusive holder of the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700194 bool IsExclusiveHeld(const Thread* self) const;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700195
196 // Assert the current thread has exclusive access to the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700197 void AssertExclusiveHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700198 if (kDebugLocking) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700199 CHECK(IsExclusiveHeld(self)) << *this;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700200 }
201 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700202 void AssertWriterHeld(const Thread* self) { AssertExclusiveHeld(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700203
204 // Assert the current thread doesn't have exclusive access to the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700205 void AssertNotExclusiveHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700206 if (kDebugLocking) {
Ian Rogers81d425b2012-09-27 16:03:43 -0700207 CHECK(!IsExclusiveHeld(self));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700208 }
209 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700210 void AssertNotWriterHeld(const Thread* self) { AssertNotExclusiveHeld(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700211
212 // Is the current thread a shared holder of the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700213 bool IsSharedHeld(const Thread* self) const;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700214
215 // Assert the current thread has shared access to the ReaderWriterMutex.
Ian Rogers81d425b2012-09-27 16:03:43 -0700216 void AssertSharedHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700217 if (kDebugLocking) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700218 CHECK(IsSharedHeld(self)) << *this;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700219 }
220 }
Ian Rogers81d425b2012-09-27 16:03:43 -0700221 void AssertReaderHeld(const Thread* self) { AssertSharedHeld(self); }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700222
223 // Assert the current thread doesn't hold this ReaderWriterMutex either in shared or exclusive
224 // mode.
Ian Rogers81d425b2012-09-27 16:03:43 -0700225 void AssertNotHeld(const Thread* self) {
Ian Rogers25fd14b2012-09-05 10:56:38 -0700226 if (kDebugLocking) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700227 CHECK(!IsSharedHeld(self)) << *this;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700228 }
Elliott Hughes8daa0922011-09-11 13:46:25 -0700229 }
230
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700231 // Id associated with exclusive owner.
232 uint64_t GetExclusiveOwnerTid() const;
Elliott Hughes8daa0922011-09-11 13:46:25 -0700233
Ian Rogers01ae5802012-09-28 16:14:01 -0700234 std::string Dump() const;
235
Ian Rogers81d425b2012-09-27 16:03:43 -0700236 private:
237#if ART_USE_FUTEXES
238 // -1 implies held exclusive, +ve shared held by state_ many owners.
239 volatile int32_t state_;
240 // Exclusive owner.
241 volatile uint64_t exclusive_owner_;
242 // Pending readers.
243 volatile int32_t num_pending_readers_;
244 // Pending writers.
245 volatile int32_t num_pending_writers_;
246#else
247 pthread_rwlock_t rwlock_;
248#endif
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700249 friend class MutexTester;
250 DISALLOW_COPY_AND_ASSIGN(ReaderWriterMutex);
251};
252
253// ConditionVariables allow threads to queue and sleep. Threads may then be resumed individually
254// (Signal) or all at once (Broadcast).
Elliott Hughes5f791332011-09-15 17:45:30 -0700255class ConditionVariable {
256 public:
Elliott Hughesa51a3dd2011-10-17 15:19:26 -0700257 explicit ConditionVariable(const std::string& name);
Elliott Hughes5f791332011-09-15 17:45:30 -0700258 ~ConditionVariable();
259
260 void Broadcast();
261 void Signal();
Ian Rogers81d425b2012-09-27 16:03:43 -0700262 void Wait(Thread* self, Mutex& mutex);
263 void TimedWait(Thread* self, Mutex& mutex, const timespec& ts);
Elliott Hughes5f791332011-09-15 17:45:30 -0700264
265 private:
266 pthread_cond_t cond_;
267 std::string name_;
268 DISALLOW_COPY_AND_ASSIGN(ConditionVariable);
269};
270
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700271// Scoped locker/unlocker for a regular Mutex that acquires mu upon construction and releases it
272// upon destruction.
273class SCOPED_LOCKABLE MutexLock {
274 public:
Ian Rogers81d425b2012-09-27 16:03:43 -0700275 explicit MutexLock(Thread* self, Mutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : self_(self), mu_(mu) {
276 mu_.ExclusiveLock(self_);
277 }
278
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700279 ~MutexLock() UNLOCK_FUNCTION() {
Ian Rogers81d425b2012-09-27 16:03:43 -0700280 mu_.ExclusiveUnlock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700281 }
282
283 private:
Ian Rogers81d425b2012-09-27 16:03:43 -0700284 Thread* const self_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700285 Mutex& mu_;
286 DISALLOW_COPY_AND_ASSIGN(MutexLock);
287};
288// Catch bug where variable name is omitted. "MutexLock (lock);" instead of "MutexLock mu(lock)".
289#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_declaration_missing_variable_name)
290
291// Scoped locker/unlocker for a ReaderWriterMutex that acquires read access to mu upon
292// construction and releases it upon destruction.
293class SCOPED_LOCKABLE ReaderMutexLock {
294 public:
Ian Rogers81d425b2012-09-27 16:03:43 -0700295 explicit ReaderMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
296 self_(self), mu_(mu) {
297 mu_.SharedLock(self_);
298 }
299
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700300 ~ReaderMutexLock() UNLOCK_FUNCTION() {
Ian Rogers81d425b2012-09-27 16:03:43 -0700301 mu_.SharedUnlock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700302 }
303
304 private:
Ian Rogers81d425b2012-09-27 16:03:43 -0700305 Thread* const self_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700306 ReaderWriterMutex& mu_;
307 DISALLOW_COPY_AND_ASSIGN(ReaderMutexLock);
308};
309// Catch bug where variable name is omitted. "ReaderMutexLock (lock);" instead of
310// "ReaderMutexLock mu(lock)".
311#define ReaderMutexLock(x) COMPILE_ASSERT(0, reader_mutex_lock_declaration_missing_variable_name)
312
313// Scoped locker/unlocker for a ReaderWriterMutex that acquires write access to mu upon
314// construction and releases it upon destruction.
315class SCOPED_LOCKABLE WriterMutexLock {
316 public:
Ian Rogers81d425b2012-09-27 16:03:43 -0700317 explicit WriterMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
318 self_(self), mu_(mu) {
319 mu_.ExclusiveLock(self_);
320 }
321
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700322 ~WriterMutexLock() UNLOCK_FUNCTION() {
Ian Rogers81d425b2012-09-27 16:03:43 -0700323 mu_.ExclusiveUnlock(self_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700324 }
325
326 private:
Ian Rogers50b35e22012-10-04 10:09:15 -0700327 Thread* const self_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700328 ReaderWriterMutex& mu_;
329 DISALLOW_COPY_AND_ASSIGN(WriterMutexLock);
330};
331// Catch bug where variable name is omitted. "WriterMutexLock (lock);" instead of
332// "WriterMutexLock mu(lock)".
333#define WriterMutexLock(x) COMPILE_ASSERT(0, writer_mutex_lock_declaration_missing_variable_name)
334
Elliott Hughes8daa0922011-09-11 13:46:25 -0700335} // namespace art
336
337#endif // ART_SRC_MUTEX_H_