mutex.h revision 00f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abac
1/* 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> 21#include <stdint.h> 22 23#include <iosfwd> 24#include <string> 25 26#include "globals.h" 27#include "gtest/gtest.h" 28#include "logging.h" 29#include "macros.h" 30 31namespace art { 32 33class LOCKABLE Mutex; 34class LOCKABLE ReaderWriterMutex; 35 36// MutexLevel is used to impose a lock hierarchy [1] where acquisition of a Mutex at a higher or 37// equal level to a lock a thread holds is invalid. The lock hierarchy achieves a cycle free 38// partial ordering and thereby cause deadlock situations to fail checks. 39// 40// [1] http://www.drdobbs.com/parallel/use-lock-hierarchies-to-avoid-deadlock/204801163 41enum MutexLevel { 42 kLoggingLock = 0, 43 kUnexpectedSignalLock = 1, 44 kThreadSuspendCountLock = 2, 45 kAbortLock = 3, 46 kDefaultMutexLevel = 4, 47 kLoadLibraryLock = 5, 48 kClassLinkerClassesLock = 6, 49 kThreadListLock = 7, 50 kHeapBitmapLock = 8, 51 kZygoteCreationLock = 9, 52 kMonitorLock = 10, 53 kMutatorLock = 11, 54 kMaxMutexLevel = kMutatorLock, 55}; 56std::ostream& operator<<(std::ostream& os, const MutexLevel& rhs); 57 58// Global mutexes corresponding to the levels above. 59class GlobalSynchronization { 60 public: 61 static void Init(); 62 63 // The mutator_lock_ is used to allow mutators to execute in a shared (reader) mode or to block 64 // mutators by having an exclusive (writer) owner. In normal execution each mutator thread holds 65 // a share on the mutator_lock_. The garbage collector may also execute with shared access but 66 // at times requires exclusive access to the heap (not to be confused with the heap meta-data 67 // guarded by the heap_lock_ below). When the garbage collector requires exclusive access it asks 68 // the mutators to suspend themselves which also involves usage of the thread_suspend_count_lock_ 69 // to cover weaknesses in using ReaderWriterMutexes with ConditionVariables. We use a condition 70 // variable to wait upon in the suspension logic as releasing and then re-acquiring a share on 71 // the mutator lock doesn't necessarily allow the exclusive user (e.g the garbage collector) 72 // chance to acquire the lock. 73 // 74 // Thread suspension: 75 // Shared users | Exclusive user 76 // (holding mutator lock and in kRunnable state) | .. running .. 77 // .. running .. | Request thread suspension by: 78 // .. running .. | - acquiring thread_suspend_count_lock_ 79 // .. running .. | - incrementing Thread::suspend_count_ on 80 // .. running .. | all mutator threads 81 // .. running .. | - releasing thread_suspend_count_lock_ 82 // .. running .. | Block trying to acquire exclusive mutator lock 83 // Poll Thread::suspend_count_ and enter full | .. blocked .. 84 // suspend code. | .. blocked .. 85 // Change state to kSuspended | .. blocked .. 86 // x: Release share on mutator_lock_ | Carry out exclusive access 87 // Acquire thread_suspend_count_lock_ | .. exclusive .. 88 // while Thread::suspend_count_ > 0 | .. exclusive .. 89 // - wait on Thread::resume_cond_ | .. exclusive .. 90 // (releases thread_suspend_count_lock_) | .. exclusive .. 91 // .. waiting .. | Release mutator_lock_ 92 // .. waiting .. | Request thread resumption by: 93 // .. waiting .. | - acquiring thread_suspend_count_lock_ 94 // .. waiting .. | - decrementing Thread::suspend_count_ on 95 // .. waiting .. | all mutator threads 96 // .. waiting .. | - notifying on Thread::resume_cond_ 97 // - re-acquire thread_suspend_count_lock_ | - releasing thread_suspend_count_lock_ 98 // Release thread_suspend_count_lock_ | .. running .. 99 // Acquire share on mutator_lock_ | .. running .. 100 // - This could block but the thread still | .. running .. 101 // has a state of kSuspended and so this | .. running .. 102 // isn't an issue. | .. running .. 103 // Acquire thread_suspend_count_lock_ | .. running .. 104 // - we poll here as we're transitioning into | .. running .. 105 // kRunnable and an individual thread suspend | .. running .. 106 // request (e.g for debugging) won't try | .. running .. 107 // to acquire the mutator lock (which would | .. running .. 108 // block as we hold the mutator lock). This | .. running .. 109 // poll ensures that if the suspender thought | .. running .. 110 // we were suspended by incrementing our | .. running .. 111 // Thread::suspend_count_ and then reading | .. running .. 112 // our state we go back to waiting on | .. running .. 113 // Thread::resume_cond_. | .. running .. 114 // can_go_runnable = Thread::suspend_count_ == 0 | .. running .. 115 // Release thread_suspend_count_lock_ | .. running .. 116 // if can_go_runnable | .. running .. 117 // Change state to kRunnable | .. running .. 118 // else | .. running .. 119 // Goto x | .. running .. 120 // .. running .. | .. running .. 121 static ReaderWriterMutex* mutator_lock_; 122 123 // Allow reader-writer mutual exclusion on the mark and live bitmaps of the heap. 124 static ReaderWriterMutex* heap_bitmap_lock_ ACQUIRED_AFTER(mutator_lock_); 125 126 // The thread_list_lock_ guards ThreadList::list_. It is also commonly held to stop threads 127 // attaching and detaching. 128 static Mutex* thread_list_lock_ ACQUIRED_AFTER(heap_bitmap_lock_); 129 130 // Guards lists of classes within the class linker. 131 static Mutex* classlinker_classes_lock_ ACQUIRED_AFTER(thread_list_lock_); 132 133 // When declaring any Mutex add DEFAULT_MUTEX_ACQUIRED_AFTER to use annotalysis to check the code 134 // doesn't try to hold a higher level Mutex. 135 #define DEFAULT_MUTEX_ACQUIRED_AFTER ACQUIRED_AFTER(classlinker_classes_lock_) 136 137 // Have an exclusive aborting thread. 138 static Mutex* abort_lock_ ACQUIRED_AFTER(classlinker_classes_lock_); 139 140 // Allow mutual exclusion when manipulating Thread::suspend_count_. 141 // TODO: Does the trade-off of a per-thread lock make sense? 142 static Mutex* thread_suspend_count_lock_ ACQUIRED_AFTER(abort_lock_); 143 144 // One unexpected signal at a time lock. 145 static Mutex* unexpected_signal_lock_ ACQUIRED_AFTER(thread_suspend_count_lock_); 146 147 // Have an exclusive logging thread. 148 static Mutex* logging_lock_ ACQUIRED_AFTER(unexpected_signal_lock_); 149}; 150 151// Base class for all Mutex implementations 152class BaseMutex { 153 public: 154 const std::string& GetName() const { 155 return name_; 156 } 157 158 virtual bool IsMutex() const { return false; } 159 virtual bool IsReaderWriterMutex() const { return false; } 160 161 protected: 162 friend class ConditionVariable; 163 164 BaseMutex(const char* name, MutexLevel level); 165 virtual ~BaseMutex() {} 166 void RegisterAsLockedWithCurrentThread(); 167 void RegisterAsUnlockedWithCurrentThread(); 168 void CheckSafeToWait(); 169 170 const MutexLevel level_; // Support for lock hierarchy. 171 const std::string name_; 172}; 173 174// A Mutex is used to achieve mutual exclusion between threads. A Mutex can be used to gain 175// exclusive access to what it guards. A Mutex can be in one of two states: 176// - Free - not owned by any thread, 177// - Exclusive - owned by a single thread. 178// 179// The effect of locking and unlocking operations on the state is: 180// State | ExclusiveLock | ExclusiveUnlock 181// ------------------------------------------- 182// Free | Exclusive | error 183// Exclusive | Block* | Free 184// * Mutex is not reentrant and so an attempt to ExclusiveLock on the same thread will result in 185// an error. Being non-reentrant simplifies Waiting on ConditionVariables. 186class LOCKABLE Mutex : public BaseMutex { 187 public: 188 explicit Mutex(const char* name, MutexLevel level = kDefaultMutexLevel, bool recursive = false); 189 ~Mutex(); 190 191 virtual bool IsMutex() const { return true; } 192 193 // Block until mutex is free then acquire exclusive access. 194 void ExclusiveLock() EXCLUSIVE_LOCK_FUNCTION(); 195 void Lock() EXCLUSIVE_LOCK_FUNCTION() { ExclusiveLock(); } 196 197 // Returns true if acquires exclusive access, false otherwise. 198 bool ExclusiveTryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true); 199 bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true) { return ExclusiveTryLock(); } 200 201 // Release exclusive access. 202 void ExclusiveUnlock() UNLOCK_FUNCTION(); 203 void Unlock() UNLOCK_FUNCTION() { ExclusiveUnlock(); } 204 205 // Is the current thread the exclusive holder of the Mutex. 206 bool IsExclusiveHeld() const; 207 208 // Assert that the Mutex is exclusively held by the current thread. 209 void AssertExclusiveHeld() { 210 if (kIsDebugBuild) { 211 CHECK(IsExclusiveHeld()); 212 } 213 } 214 void AssertHeld() { AssertExclusiveHeld(); } 215 216 // Assert that the Mutex is not held by the current thread. 217 void AssertNotHeldExclusive() { 218 if (kIsDebugBuild) { 219 CHECK(!IsExclusiveHeld()); 220 } 221 } 222 void AssertNotHeld() { AssertNotHeldExclusive(); } 223 224 // Id associated with exclusive owner. 225 uint64_t GetExclusiveOwnerTid() const; 226 227 // Returns how many times this Mutex has been locked, it is better to use AssertHeld/NotHeld. 228 unsigned int GetDepth() const { 229 return recursion_count_; 230 } 231 232 private: 233 pthread_mutex_t mutex_; 234 const bool recursive_; // Can the lock be recursively held? 235 unsigned int recursion_count_; 236 friend class ConditionVariable; 237 friend class MutexTester; 238 DISALLOW_COPY_AND_ASSIGN(Mutex); 239}; 240 241// A ReaderWriterMutex is used to achieve mutual exclusion between threads, similar to a Mutex. 242// Unlike a Mutex a ReaderWriterMutex can be used to gain exclusive (writer) or shared (reader) 243// access to what it guards. A flaw in relation to a Mutex is that it cannot be used with a 244// condition variable. A ReaderWriterMutex can be in one of three states: 245// - Free - not owned by any thread, 246// - Exclusive - owned by a single thread, 247// - Shared(n) - shared amongst n threads. 248// 249// The effect of locking and unlocking operations on the state is: 250// 251// State | ExclusiveLock | ExclusiveUnlock | SharedLock | SharedUnlock 252// ---------------------------------------------------------------------------- 253// Free | Exclusive | error | SharedLock(1) | error 254// Exclusive | Block | Free | Block | error 255// Shared(n) | Block | error | SharedLock(n+1)* | Shared(n-1) or Free 256// * for large values of n the SharedLock may block. 257class LOCKABLE ReaderWriterMutex : public BaseMutex { 258 public: 259 explicit ReaderWriterMutex(const char* name, MutexLevel level = kDefaultMutexLevel); 260 ~ReaderWriterMutex(); 261 262 virtual bool IsReaderWriterMutex() const { return true; } 263 264 // Block until ReaderWriterMutex is free then acquire exclusive access. 265 void ExclusiveLock() EXCLUSIVE_LOCK_FUNCTION(); 266 void WriterLock() EXCLUSIVE_LOCK_FUNCTION() { ExclusiveLock(); } 267 268 // Release exclusive access. 269 void ExclusiveUnlock() UNLOCK_FUNCTION(); 270 void WriterUnlock() UNLOCK_FUNCTION() { ExclusiveUnlock(); } 271 272 // Block until ReaderWriterMutex is free and acquire exclusive access. Returns true on success 273 // or false if timeout is reached. 274 bool ExclusiveLockWithTimeout(const timespec& abs_timeout) EXCLUSIVE_TRYLOCK_FUNCTION(true); 275 276 // Block until ReaderWriterMutex is shared or free then acquire a share on the access. 277 void SharedLock() SHARED_LOCK_FUNCTION(); 278 void ReaderLock() SHARED_LOCK_FUNCTION() { SharedLock(); } 279 280 // Try to acquire share of ReaderWriterMutex. 281 bool SharedTryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true); 282 283 // Release a share of the access. 284 void SharedUnlock() UNLOCK_FUNCTION(); 285 void ReaderUnlock() UNLOCK_FUNCTION() { SharedUnlock(); } 286 287 // Is the current thread the exclusive holder of the ReaderWriterMutex. 288 bool IsExclusiveHeld() const; 289 290 // Assert the current thread has exclusive access to the ReaderWriterMutex. 291 void AssertExclusiveHeld() { 292 if (kIsDebugBuild) { 293 CHECK(IsExclusiveHeld()); 294 } 295 } 296 void AssertWriterHeld() { AssertExclusiveHeld(); } 297 298 // Assert the current thread doesn't have exclusive access to the ReaderWriterMutex. 299 void AssertNotExclusiveHeld() { 300 if (kIsDebugBuild) { 301 CHECK(!IsExclusiveHeld()); 302 } 303 } 304 void AssertNotWriterHeld() { AssertNotExclusiveHeld(); } 305 306 // Is the current thread a shared holder of the ReaderWriterMutex. 307 bool IsSharedHeld() const; 308 309 // Assert the current thread has shared access to the ReaderWriterMutex. 310 void AssertSharedHeld() { 311 if (kIsDebugBuild) { 312 CHECK(IsSharedHeld()); 313 } 314 } 315 void AssertReaderHeld() { AssertSharedHeld(); } 316 317 // Assert the current thread doesn't hold this ReaderWriterMutex either in shared or exclusive 318 // mode. 319 void AssertNotHeld() { 320 if (kIsDebugBuild) { 321 CHECK(!IsSharedHeld()); 322 } 323 } 324 325 // Id associated with exclusive owner. 326 uint64_t GetExclusiveOwnerTid() const; 327 private: 328 pthread_rwlock_t rwlock_; 329 330 friend class MutexTester; 331 DISALLOW_COPY_AND_ASSIGN(ReaderWriterMutex); 332}; 333 334// ConditionVariables allow threads to queue and sleep. Threads may then be resumed individually 335// (Signal) or all at once (Broadcast). 336class ConditionVariable { 337 public: 338 explicit ConditionVariable(const std::string& name); 339 ~ConditionVariable(); 340 341 void Broadcast(); 342 void Signal(); 343 void Wait(Mutex& mutex); 344 void TimedWait(Mutex& mutex, const timespec& ts); 345 346 private: 347 pthread_cond_t cond_; 348 std::string name_; 349 DISALLOW_COPY_AND_ASSIGN(ConditionVariable); 350}; 351 352// Scoped locker/unlocker for a regular Mutex that acquires mu upon construction and releases it 353// upon destruction. 354class SCOPED_LOCKABLE MutexLock { 355 public: 356 explicit MutexLock(Mutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : mu_(mu) { 357 mu_.ExclusiveLock(); 358 } 359 360 ~MutexLock() UNLOCK_FUNCTION() { 361 mu_.ExclusiveUnlock(); 362 } 363 364 private: 365 Mutex& mu_; 366 DISALLOW_COPY_AND_ASSIGN(MutexLock); 367}; 368// Catch bug where variable name is omitted. "MutexLock (lock);" instead of "MutexLock mu(lock)". 369#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_declaration_missing_variable_name) 370 371// Scoped locker/unlocker for a ReaderWriterMutex that acquires read access to mu upon 372// construction and releases it upon destruction. 373class SCOPED_LOCKABLE ReaderMutexLock { 374 public: 375 explicit ReaderMutexLock(ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : mu_(mu) { 376 mu_.SharedLock(); 377 } 378 379 ~ReaderMutexLock() UNLOCK_FUNCTION() { 380 mu_.SharedUnlock(); 381 } 382 383 private: 384 ReaderWriterMutex& mu_; 385 DISALLOW_COPY_AND_ASSIGN(ReaderMutexLock); 386}; 387// Catch bug where variable name is omitted. "ReaderMutexLock (lock);" instead of 388// "ReaderMutexLock mu(lock)". 389#define ReaderMutexLock(x) COMPILE_ASSERT(0, reader_mutex_lock_declaration_missing_variable_name) 390 391// Scoped locker/unlocker for a ReaderWriterMutex that acquires write access to mu upon 392// construction and releases it upon destruction. 393class SCOPED_LOCKABLE WriterMutexLock { 394 public: 395 explicit WriterMutexLock(ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : mu_(mu) { 396 mu_.ExclusiveLock(); 397 } 398 399 ~WriterMutexLock() UNLOCK_FUNCTION() { 400 mu_.ExclusiveUnlock(); 401 } 402 403 private: 404 ReaderWriterMutex& mu_; 405 DISALLOW_COPY_AND_ASSIGN(WriterMutexLock); 406}; 407// Catch bug where variable name is omitted. "WriterMutexLock (lock);" instead of 408// "WriterMutexLock mu(lock)". 409#define WriterMutexLock(x) COMPILE_ASSERT(0, writer_mutex_lock_declaration_missing_variable_name) 410 411// Scoped unlocker/locker for a ReaderWriterMutex that releases read access to mu upon 412// construction and acquires it again upon destruction. 413class ReaderMutexUnlock { 414 public: 415 explicit ReaderMutexUnlock(ReaderWriterMutex& mu) UNLOCK_FUNCTION(mu) : mu_(mu) { 416 mu_.SharedUnlock(); 417 } 418 419 ~ReaderMutexUnlock() SHARED_LOCK_FUNCTION(mu_) { 420 mu_.SharedLock(); 421 } 422 423 private: 424 ReaderWriterMutex& mu_; 425 DISALLOW_COPY_AND_ASSIGN(ReaderMutexUnlock); 426}; 427// Catch bug where variable name is omitted. "ReaderMutexUnlock (lock);" instead of 428// "ReaderMutexUnlock mu(lock)". 429#define ReaderMutexUnlock(x) \ 430 COMPILE_ASSERT(0, reader_mutex_unlock_declaration_missing_variable_name) 431 432} // namespace art 433 434#endif // ART_SRC_MUTEX_H_ 435