mutex.h revision ab47016374d340011680e9cd970ee7d6225d6704
18daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes/* 28daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Copyright (C) 2011 The Android Open Source Project 38daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * 48daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 58daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * you may not use this file except in compliance with the License. 68daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * You may obtain a copy of the License at 78daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * 88daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 98daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * 108daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Unless required by applicable law or agreed to in writing, software 118daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 128daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * See the License for the specific language governing permissions and 148daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * limitations under the License. 158daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes */ 168daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 178daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#ifndef ART_SRC_MUTEX_H_ 188daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#define ART_SRC_MUTEX_H_ 198daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 208daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include <pthread.h> 21cd74c4b3a6893c876c6e03fd99a1264249653d80Brian Carlstrom#include <stdint.h> 22ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes 23ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes#include <iosfwd> 248daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include <string> 258daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 2600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "globals.h" 2781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers#include "locks.h" 288daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include "macros.h" 2981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers#include "thread.h" 3081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers 31ab47016374d340011680e9cd970ee7d6225d6704Ian Rogers#if defined(__APPLE__) 3281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers#define ART_USE_FUTEXES 0 33ab47016374d340011680e9cd970ee7d6225d6704Ian Rogers#else 34ab47016374d340011680e9cd970ee7d6225d6704Ian Rogers#define ART_USE_FUTEXES 1 35ab47016374d340011680e9cd970ee7d6225d6704Ian Rogers#endif 368daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 3766aee5cd571cf4739d2735769304202ea5051fb8Ian Rogers// Currently Darwin doesn't support locks with timeouts. 3866aee5cd571cf4739d2735769304202ea5051fb8Ian Rogers#if !defined(__APPLE__) 3966aee5cd571cf4739d2735769304202ea5051fb8Ian Rogers#define HAVE_TIMED_RWLOCK 1 4066aee5cd571cf4739d2735769304202ea5051fb8Ian Rogers#else 4166aee5cd571cf4739d2735769304202ea5051fb8Ian Rogers#define HAVE_TIMED_RWLOCK 0 4266aee5cd571cf4739d2735769304202ea5051fb8Ian Rogers#endif 4366aee5cd571cf4739d2735769304202ea5051fb8Ian Rogers 448daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesnamespace art { 458daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 4625fd14b87cced64a179dee885573113be5e11944Ian Rogersconst bool kDebugLocking = kIsDebugBuild; 4725fd14b87cced64a179dee885573113be5e11944Ian Rogers 4800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Base class for all Mutex implementations 4900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersclass BaseMutex { 5000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers public: 5100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const std::string& GetName() const { 5200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return name_; 5300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 5400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 5500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers virtual bool IsMutex() const { return false; } 5600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers virtual bool IsReaderWriterMutex() const { return false; } 5700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 5800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers protected: 5900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers friend class ConditionVariable; 6000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 6181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers BaseMutex(const char* name, LockLevel level); 6200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers virtual ~BaseMutex() {} 6381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void RegisterAsLocked(Thread* self); 6481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void RegisterAsUnlocked(Thread* self); 6581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void CheckSafeToWait(Thread* self); 6600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 6781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers const LockLevel level_; // Support for lock hierarchy. 680a1038b0a30a52dff1a449a989825e808a83df80Elliott Hughes const std::string name_; 6900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers}; 7000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 7100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// A Mutex is used to achieve mutual exclusion between threads. A Mutex can be used to gain 7200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// exclusive access to what it guards. A Mutex can be in one of two states: 7300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// - Free - not owned by any thread, 7400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// - Exclusive - owned by a single thread. 7500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// 7600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// The effect of locking and unlocking operations on the state is: 7700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// State | ExclusiveLock | ExclusiveUnlock 7800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// ------------------------------------------- 7900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Free | Exclusive | error 8000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Exclusive | Block* | Free 8100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// * Mutex is not reentrant and so an attempt to ExclusiveLock on the same thread will result in 8200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// an error. Being non-reentrant simplifies Waiting on ConditionVariables. 8301ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogersstd::ostream& operator<<(std::ostream& os, const Mutex& mu); 8400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersclass LOCKABLE Mutex : public BaseMutex { 8500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers public: 8681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers explicit Mutex(const char* name, LockLevel level = kDefaultMutexLevel, bool recursive = false); 8700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ~Mutex(); 8800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 8900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers virtual bool IsMutex() const { return true; } 9000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 9100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Block until mutex is free then acquire exclusive access. 9281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void ExclusiveLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION(); 9381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void Lock(Thread* self) EXCLUSIVE_LOCK_FUNCTION() { ExclusiveLock(self); } 9400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 9500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Returns true if acquires exclusive access, false otherwise. 9681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers bool ExclusiveTryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true); 9781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers bool TryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true) { return ExclusiveTryLock(self); } 9800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 9900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Release exclusive access. 10081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void ExclusiveUnlock(Thread* self) UNLOCK_FUNCTION(); 10181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void Unlock(Thread* self) UNLOCK_FUNCTION() { ExclusiveUnlock(self); } 10200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 10300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Is the current thread the exclusive holder of the Mutex. 10481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers bool IsExclusiveHeld(const Thread* self) const; 1058daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 10600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Assert that the Mutex is exclusively held by the current thread. 10781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void AssertExclusiveHeld(const Thread* self) { 10825fd14b87cced64a179dee885573113be5e11944Ian Rogers if (kDebugLocking) { 10901ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers CHECK(IsExclusiveHeld(self)) << *this; 11000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 11100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 11281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void AssertHeld(const Thread* self) { AssertExclusiveHeld(self); } 11381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void AssertHeld() { AssertExclusiveHeld(Thread::Current()); } 11400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 11500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Assert that the Mutex is not held by the current thread. 11681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void AssertNotHeldExclusive(const Thread* self) { 11725fd14b87cced64a179dee885573113be5e11944Ian Rogers if (kDebugLocking) { 11801ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers CHECK(!IsExclusiveHeld(self)) << *this; 11900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 12000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 12181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void AssertNotHeld(const Thread* self) { AssertNotHeldExclusive(self); } 12200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 12300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Id associated with exclusive owner. 12400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers uint64_t GetExclusiveOwnerTid() const; 12500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 12600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Returns how many times this Mutex has been locked, it is better to use AssertHeld/NotHeld. 12700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers unsigned int GetDepth() const { 12800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return recursion_count_; 12900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 13000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 13101ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers std::string Dump() const; 13201ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers 13300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers private: 13400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers pthread_mutex_t mutex_; 13500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const bool recursive_; // Can the lock be recursively held? 13600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers unsigned int recursion_count_; 137f1498437b0d6beb9f4f91980b98cbeb0b5c773ceElliott Hughes friend class ConditionVariable; 1383efb8416c9809a1da3300509fd9d2bc54e22e4c2Elliott Hughes friend class MutexTester; 1398daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes DISALLOW_COPY_AND_ASSIGN(Mutex); 1408daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes}; 1418daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 14200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// A ReaderWriterMutex is used to achieve mutual exclusion between threads, similar to a Mutex. 14300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Unlike a Mutex a ReaderWriterMutex can be used to gain exclusive (writer) or shared (reader) 14400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// access to what it guards. A flaw in relation to a Mutex is that it cannot be used with a 14500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// condition variable. A ReaderWriterMutex can be in one of three states: 14600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// - Free - not owned by any thread, 14700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// - Exclusive - owned by a single thread, 14800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// - Shared(n) - shared amongst n threads. 14900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// 15000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// The effect of locking and unlocking operations on the state is: 15100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// 15200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// State | ExclusiveLock | ExclusiveUnlock | SharedLock | SharedUnlock 15300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// ---------------------------------------------------------------------------- 15400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Free | Exclusive | error | SharedLock(1) | error 15500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Exclusive | Block | Free | Block | error 15600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Shared(n) | Block | error | SharedLock(n+1)* | Shared(n-1) or Free 15700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// * for large values of n the SharedLock may block. 15801ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogersstd::ostream& operator<<(std::ostream& os, const ReaderWriterMutex& mu); 15900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersclass LOCKABLE ReaderWriterMutex : public BaseMutex { 1608daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes public: 16181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers explicit ReaderWriterMutex(const char* name, LockLevel level = kDefaultMutexLevel); 16200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ~ReaderWriterMutex(); 16300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 16400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers virtual bool IsReaderWriterMutex() const { return true; } 16500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 16600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Block until ReaderWriterMutex is free then acquire exclusive access. 16781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void ExclusiveLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION(); 16881d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void WriterLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION() { ExclusiveLock(self); } 16900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 17000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Release exclusive access. 17181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void ExclusiveUnlock(Thread* self) UNLOCK_FUNCTION(); 17281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void WriterUnlock(Thread* self) UNLOCK_FUNCTION() { ExclusiveUnlock(self); } 17300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 17400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Block until ReaderWriterMutex is free and acquire exclusive access. Returns true on success 17500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // or false if timeout is reached. 17666aee5cd571cf4739d2735769304202ea5051fb8Ian Rogers#if HAVE_TIMED_RWLOCK 17781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers bool ExclusiveLockWithTimeout(Thread* self, const timespec& abs_timeout) 17881d425b0b232962441616f8b14f73620bffef5e5Ian Rogers EXCLUSIVE_TRYLOCK_FUNCTION(true); 17966aee5cd571cf4739d2735769304202ea5051fb8Ian Rogers#endif 18000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 18100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Block until ReaderWriterMutex is shared or free then acquire a share on the access. 18281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void SharedLock(Thread* self) SHARED_LOCK_FUNCTION(); 18381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void ReaderLock(Thread* self) SHARED_LOCK_FUNCTION() { SharedLock(self); } 18400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 18500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Try to acquire share of ReaderWriterMutex. 18681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers bool SharedTryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true); 18700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 18800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Release a share of the access. 18981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void SharedUnlock(Thread* self) UNLOCK_FUNCTION(); 19081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void ReaderUnlock(Thread* self) UNLOCK_FUNCTION() { SharedUnlock(self); } 19100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 19200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Is the current thread the exclusive holder of the ReaderWriterMutex. 19381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers bool IsExclusiveHeld(const Thread* self) const; 19400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 19500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Assert the current thread has exclusive access to the ReaderWriterMutex. 19681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void AssertExclusiveHeld(const Thread* self) { 19725fd14b87cced64a179dee885573113be5e11944Ian Rogers if (kDebugLocking) { 19801ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers CHECK(IsExclusiveHeld(self)) << *this; 19900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 2008daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes } 20181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void AssertWriterHeld(const Thread* self) { AssertExclusiveHeld(self); } 2028daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 20300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Assert the current thread doesn't have exclusive access to the ReaderWriterMutex. 20481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void AssertNotExclusiveHeld(const Thread* self) { 20525fd14b87cced64a179dee885573113be5e11944Ian Rogers if (kDebugLocking) { 20681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers CHECK(!IsExclusiveHeld(self)); 20700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 20800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 20981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void AssertNotWriterHeld(const Thread* self) { AssertNotExclusiveHeld(self); } 21000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 21100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Is the current thread a shared holder of the ReaderWriterMutex. 21281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers bool IsSharedHeld(const Thread* self) const; 21300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 21400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Assert the current thread has shared access to the ReaderWriterMutex. 21581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void AssertSharedHeld(const Thread* self) { 21625fd14b87cced64a179dee885573113be5e11944Ian Rogers if (kDebugLocking) { 21701ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers CHECK(IsSharedHeld(self)) << *this; 21800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 2198daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes } 22081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void AssertReaderHeld(const Thread* self) { AssertSharedHeld(self); } 2218daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 22200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Assert the current thread doesn't hold this ReaderWriterMutex either in shared or exclusive 22300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // mode. 22481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void AssertNotHeld(const Thread* self) { 22525fd14b87cced64a179dee885573113be5e11944Ian Rogers if (kDebugLocking) { 22601ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers CHECK(!IsSharedHeld(self)) << *this; 22700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 22800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 22900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 23000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Id associated with exclusive owner. 23100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers uint64_t GetExclusiveOwnerTid() const; 23281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers 23301ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers std::string Dump() const; 23401ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers 2358daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes private: 23681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers#if ART_USE_FUTEXES 23781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers // -1 implies held exclusive, +ve shared held by state_ many owners. 23881d425b0b232962441616f8b14f73620bffef5e5Ian Rogers volatile int32_t state_; 23981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers // Exclusive owner. 24081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers volatile uint64_t exclusive_owner_; 24181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers // Pending readers. 24281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers volatile int32_t num_pending_readers_; 24381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers // Pending writers. 24481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers volatile int32_t num_pending_writers_; 24581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers#else 24600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers pthread_rwlock_t rwlock_; 24781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers#endif 24800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers friend class MutexTester; 24900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers DISALLOW_COPY_AND_ASSIGN(ReaderWriterMutex); 2508daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes}; 2518daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 25200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// ConditionVariables allow threads to queue and sleep. Threads may then be resumed individually 25300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// (Signal) or all at once (Broadcast). 2545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesclass ConditionVariable { 2555f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes public: 256a51a3dd5603daf3d368b7735067e1d9eb54c4c40Elliott Hughes explicit ConditionVariable(const std::string& name); 2575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ~ConditionVariable(); 2585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 2595f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes void Broadcast(); 2605f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes void Signal(); 26181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void Wait(Thread* self, Mutex& mutex); 26281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers void TimedWait(Thread* self, Mutex& mutex, const timespec& ts); 2635f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 2645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes private: 2655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes pthread_cond_t cond_; 2665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes std::string name_; 2675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DISALLOW_COPY_AND_ASSIGN(ConditionVariable); 2685f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}; 2695f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 27000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Scoped locker/unlocker for a regular Mutex that acquires mu upon construction and releases it 27100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// upon destruction. 27200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersclass SCOPED_LOCKABLE MutexLock { 27300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers public: 27481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers explicit MutexLock(Thread* self, Mutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : self_(self), mu_(mu) { 27581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers mu_.ExclusiveLock(self_); 27681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers } 27781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers 27881d425b0b232962441616f8b14f73620bffef5e5Ian Rogers explicit MutexLock(Mutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : self_(Thread::Current()), mu_(mu) { 27981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers mu_.ExclusiveLock(self_); 28000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 28100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 28200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ~MutexLock() UNLOCK_FUNCTION() { 28381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers mu_.ExclusiveUnlock(self_); 28400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 28500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 28600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers private: 28781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers Thread* const self_; 28800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Mutex& mu_; 28900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers DISALLOW_COPY_AND_ASSIGN(MutexLock); 29000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers}; 29100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Catch bug where variable name is omitted. "MutexLock (lock);" instead of "MutexLock mu(lock)". 29200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_declaration_missing_variable_name) 29300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 29400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Scoped locker/unlocker for a ReaderWriterMutex that acquires read access to mu upon 29500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// construction and releases it upon destruction. 29600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersclass SCOPED_LOCKABLE ReaderMutexLock { 29700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers public: 29881d425b0b232962441616f8b14f73620bffef5e5Ian Rogers explicit ReaderMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : 29981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers self_(self), mu_(mu) { 30081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers mu_.SharedLock(self_); 30181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers } 30281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers 30381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers explicit ReaderMutexLock(ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : 30481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers self_(Thread::Current()), mu_(mu) { 30581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers mu_.SharedLock(self_); 30600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 30700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 30800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ~ReaderMutexLock() UNLOCK_FUNCTION() { 30981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers mu_.SharedUnlock(self_); 31000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 31100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 31200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers private: 31381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers Thread* const self_; 31400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ReaderWriterMutex& mu_; 31500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers DISALLOW_COPY_AND_ASSIGN(ReaderMutexLock); 31600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers}; 31700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Catch bug where variable name is omitted. "ReaderMutexLock (lock);" instead of 31800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// "ReaderMutexLock mu(lock)". 31900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#define ReaderMutexLock(x) COMPILE_ASSERT(0, reader_mutex_lock_declaration_missing_variable_name) 32000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 32100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Scoped locker/unlocker for a ReaderWriterMutex that acquires write access to mu upon 32200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// construction and releases it upon destruction. 32300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersclass SCOPED_LOCKABLE WriterMutexLock { 32400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers public: 32581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers explicit WriterMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : 32681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers self_(self), mu_(mu) { 32781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers mu_.ExclusiveLock(self_); 32881d425b0b232962441616f8b14f73620bffef5e5Ian Rogers } 32981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers 33081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers explicit WriterMutexLock(ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : 33181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers self_(Thread::Current()), mu_(mu) { 33281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers mu_.ExclusiveLock(self_); 33300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 33400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 33500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ~WriterMutexLock() UNLOCK_FUNCTION() { 33681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers mu_.ExclusiveUnlock(self_); 33700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 33800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 33900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers private: 34081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers Thread* self_; 34100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ReaderWriterMutex& mu_; 34200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers DISALLOW_COPY_AND_ASSIGN(WriterMutexLock); 34300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers}; 34400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Catch bug where variable name is omitted. "WriterMutexLock (lock);" instead of 34500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// "WriterMutexLock mu(lock)". 34600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#define WriterMutexLock(x) COMPILE_ASSERT(0, writer_mutex_lock_declaration_missing_variable_name) 34700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 3488daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes} // namespace art 3498daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 3508daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#endif // ART_SRC_MUTEX_H_ 351