mutex.h revision 81d425b0b232962441616f8b14f73620bffef5e5
15ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov/* 25ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov * Copyright (C) 2011 The Android Open Source Project 35ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov * 45ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov * Licensed under the Apache License, Version 2.0 (the "License"); 55ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov * you may not use this file except in compliance with the License. 65ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov * You may obtain a copy of the License at 75ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov * 85ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov * http://www.apache.org/licenses/LICENSE-2.0 95ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov * 105ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov * Unless required by applicable law or agreed to in writing, software 115ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov * distributed under the License is distributed on an "AS IS" BASIS, 125ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov * See the License for the specific language governing permissions and 145ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov * limitations under the License. 155ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov */ 165ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 175ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov#ifndef ART_SRC_MUTEX_H_ 185ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov#define ART_SRC_MUTEX_H_ 195ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 20c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe#include <pthread.h> 215ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov#include <stdint.h> 225ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 2309659c22dc2f2c85a0ade965d1fc5160944b8692Andreas Gampe#include <iosfwd> 245ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov#include <string> 255ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 26c15a2f4f45661a7f5f542e406282c146ea1a968dAndreas Gampe#include "globals.h" 27c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe#include "locks.h" 28c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe#include "macros.h" 29c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe#include "thread.h" 30b486a98aadc95d80548953410cf23edba62259faAndreas Gampe 315ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov#define ART_USE_FUTEXES 0 325ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 335ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// Currently Darwin doesn't support locks with timeouts. 345ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov#if !defined(__APPLE__) 355ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov#define HAVE_TIMED_RWLOCK 1 365ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov#else 375ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov#define HAVE_TIMED_RWLOCK 0 385ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov#endif 395ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 405ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilovnamespace art { 415ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 425ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilovconst bool kDebugLocking = kIsDebugBuild; 435ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 445ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// Base class for all Mutex implementations 455ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilovclass BaseMutex { 465ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov public: 475ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov const std::string& GetName() const { 485ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov return name_; 4953463ba8717fc93379ebf2b0c04a9a2c85382973xueliang.zhong } 505ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 51c032e74b57d31861b6bb55500016ebb5476eb142xueliang.zhong virtual bool IsMutex() const { return false; } 525ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov virtual bool IsReaderWriterMutex() const { return false; } 535ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 545ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov protected: 555ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov friend class ConditionVariable; 56c032e74b57d31861b6bb55500016ebb5476eb142xueliang.zhong 575ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov BaseMutex(const char* name, LockLevel level); 585ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov virtual ~BaseMutex() {} 595ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void RegisterAsLocked(Thread* self); 600fb3719129098110a61f320cb47edf774166b602Artem Serov void RegisterAsUnlocked(Thread* self); 610fb3719129098110a61f320cb47edf774166b602Artem Serov void CheckSafeToWait(Thread* self); 620fb3719129098110a61f320cb47edf774166b602Artem Serov 635ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov const LockLevel level_; // Support for lock hierarchy. 645ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov const std::string name_; 655ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov}; 665ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 675ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// A Mutex is used to achieve mutual exclusion between threads. A Mutex can be used to gain 68ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko// exclusive access to what it guards. A Mutex can be in one of two states: 695ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// - Free - not owned by any thread, 705ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// - Exclusive - owned by a single thread. 715ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// 725ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// The effect of locking and unlocking operations on the state is: 735ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// State | ExclusiveLock | ExclusiveUnlock 745ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// ------------------------------------------- 755ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// Free | Exclusive | error 765ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// Exclusive | Block* | Free 775ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// * Mutex is not reentrant and so an attempt to ExclusiveLock on the same thread will result in 785ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// an error. Being non-reentrant simplifies Waiting on ConditionVariables. 795ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilovclass LOCKABLE Mutex : public BaseMutex { 805ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov public: 815ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov explicit Mutex(const char* name, LockLevel level = kDefaultMutexLevel, bool recursive = false); 825ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov ~Mutex(); 835ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 845ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov virtual bool IsMutex() const { return true; } 855ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 865ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Block until mutex is free then acquire exclusive access. 87d4cc5b2127894475160b5d2bba9791dd21af5953Artem Serov void ExclusiveLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION(); 885ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void Lock(Thread* self) EXCLUSIVE_LOCK_FUNCTION() { ExclusiveLock(self); } 895ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 905ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Returns true if acquires exclusive access, false otherwise. 915ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov bool ExclusiveTryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true); 925ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov bool TryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true) { return ExclusiveTryLock(self); } 935ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 945ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Release exclusive access. 955ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void ExclusiveUnlock(Thread* self) UNLOCK_FUNCTION(); 965ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void Unlock(Thread* self) UNLOCK_FUNCTION() { ExclusiveUnlock(self); } 975ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 985ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Is the current thread the exclusive holder of the Mutex. 995ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov bool IsExclusiveHeld(const Thread* self) const; 1005ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 101e7197bf7d58c705a048e13e241d7ca320502cd40Vladimir Marko // Assert that the Mutex is exclusively held by the current thread. 1025ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void AssertExclusiveHeld(const Thread* self) { 103e7197bf7d58c705a048e13e241d7ca320502cd40Vladimir Marko if (kDebugLocking) { 1045ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov CHECK(IsExclusiveHeld(self)); 1055ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 1065ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 1075ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void AssertHeld(const Thread* self) { AssertExclusiveHeld(self); } 1085ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void AssertHeld() { AssertExclusiveHeld(Thread::Current()); } 1095ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 1105ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Assert that the Mutex is not held by the current thread. 1115ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void AssertNotHeldExclusive(const Thread* self) { 1125ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov if (kDebugLocking) { 1135ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov CHECK(!IsExclusiveHeld(self)); 1145ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 1155ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 1165ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void AssertNotHeld(const Thread* self) { AssertNotHeldExclusive(self); } 1175ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 1185ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Id associated with exclusive owner. 1195ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov uint64_t GetExclusiveOwnerTid() const; 1205ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 1215ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Returns how many times this Mutex has been locked, it is better to use AssertHeld/NotHeld. 1225ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov unsigned int GetDepth() const { 1235ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov return recursion_count_; 1245ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 1255ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 1265ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov private: 1279cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain pthread_mutex_t mutex_; 1289cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain const bool recursive_; // Can the lock be recursively held? 1290ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko unsigned int recursion_count_; 1309cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain friend class ConditionVariable; 1319cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain friend class MutexTester; 1329cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain DISALLOW_COPY_AND_ASSIGN(Mutex); 1339cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain}; 1340ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko 1359cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain// A ReaderWriterMutex is used to achieve mutual exclusion between threads, similar to a Mutex. 1360ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko// Unlike a Mutex a ReaderWriterMutex can be used to gain exclusive (writer) or shared (reader) 1370ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko// access to what it guards. A flaw in relation to a Mutex is that it cannot be used with a 1380ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko// condition variable. A ReaderWriterMutex can be in one of three states: 1399cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain// - Free - not owned by any thread, 1409cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain// - Exclusive - owned by a single thread, 1419cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain// - Shared(n) - shared amongst n threads. 1429cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain// 1439cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain// The effect of locking and unlocking operations on the state is: 1449cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain// 1459cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain// State | ExclusiveLock | ExclusiveUnlock | SharedLock | SharedUnlock 1469cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain// ---------------------------------------------------------------------------- 1479cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain// Free | Exclusive | error | SharedLock(1) | error 1489cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain// Exclusive | Block | Free | Block | error 1499cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain// Shared(n) | Block | error | SharedLock(n+1)* | Shared(n-1) or Free 1509cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain// * for large values of n the SharedLock may block. 1519cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillainclass LOCKABLE ReaderWriterMutex : public BaseMutex { 1520ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko public: 1539cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain explicit ReaderWriterMutex(const char* name, LockLevel level = kDefaultMutexLevel); 1549cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain ~ReaderWriterMutex(); 1559cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain 1569cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain virtual bool IsReaderWriterMutex() const { return true; } 1570ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko 1589cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain // Block until ReaderWriterMutex is free then acquire exclusive access. 1590ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko void ExclusiveLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION(); 1600ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko void WriterLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION() { ExclusiveLock(self); } 1610ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko 1629cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain // Release exclusive access. 1639cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain void ExclusiveUnlock(Thread* self) UNLOCK_FUNCTION(); 1649cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain void WriterUnlock(Thread* self) UNLOCK_FUNCTION() { ExclusiveUnlock(self); } 1659cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain 1669cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain // Block until ReaderWriterMutex is free and acquire exclusive access. Returns true on success 1679cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain // or false if timeout is reached. 1689cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain#if HAVE_TIMED_RWLOCK 1699cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain bool ExclusiveLockWithTimeout(Thread* self, const timespec& abs_timeout) 1709cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain EXCLUSIVE_TRYLOCK_FUNCTION(true); 1715ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov#endif 1725ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 1735ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Block until ReaderWriterMutex is shared or free then acquire a share on the access. 1745ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void SharedLock(Thread* self) SHARED_LOCK_FUNCTION(); 1755ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void ReaderLock(Thread* self) SHARED_LOCK_FUNCTION() { SharedLock(self); } 1765ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 1775ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Try to acquire share of ReaderWriterMutex. 1785ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov bool SharedTryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true); 1795ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 1805ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Release a share of the access. 1815ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void SharedUnlock(Thread* self) UNLOCK_FUNCTION(); 1825ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void ReaderUnlock(Thread* self) UNLOCK_FUNCTION() { SharedUnlock(self); } 1835ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 1845ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Is the current thread the exclusive holder of the ReaderWriterMutex. 1855ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov bool IsExclusiveHeld(const Thread* self) const; 1865ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 1875ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Assert the current thread has exclusive access to the ReaderWriterMutex. 1885ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void AssertExclusiveHeld(const Thread* self) { 1895ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov if (kDebugLocking) { 1905ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov CHECK(IsExclusiveHeld(self)); 1910ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko } 1920ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko } 1935ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void AssertWriterHeld(const Thread* self) { AssertExclusiveHeld(self); } 1945ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 1955ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Assert the current thread doesn't have exclusive access to the ReaderWriterMutex. 1965ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void AssertNotExclusiveHeld(const Thread* self) { 1975ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov if (kDebugLocking) { 1985ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov CHECK(!IsExclusiveHeld(self)); 1995ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 2005ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 2015ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void AssertNotWriterHeld(const Thread* self) { AssertNotExclusiveHeld(self); } 2025ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 2039cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain // Is the current thread a shared holder of the ReaderWriterMutex. 2045ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov bool IsSharedHeld(const Thread* self) const; 2055ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 2065ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Assert the current thread has shared access to the ReaderWriterMutex. 2075ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void AssertSharedHeld(const Thread* self) { 2085ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov if (kDebugLocking) { 2095ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov CHECK(IsSharedHeld(self)); 2105ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 2115ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 2125ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void AssertReaderHeld(const Thread* self) { AssertSharedHeld(self); } 2135ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 2145ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Assert the current thread doesn't hold this ReaderWriterMutex either in shared or exclusive 2155ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // mode. 2165ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void AssertNotHeld(const Thread* self) { 2175ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov if (kDebugLocking) { 2185ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov CHECK(!IsSharedHeld(self)); 2195ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 2205ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 2215ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 2225ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Id associated with exclusive owner. 2235ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov uint64_t GetExclusiveOwnerTid() const; 2245ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 2255ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov private: 2265ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov#if ART_USE_FUTEXES 2279cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain // -1 implies held exclusive, +ve shared held by state_ many owners. 2289cc0ea8140e0106e132efc3c1c5c458fa196ae41Roland Levillain volatile int32_t state_; 2295ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Exclusive owner. 23097c46466aea25ab63a99b3d1afc558f0d9f55abbRoland Levillain volatile uint64_t exclusive_owner_; 2315ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Pending readers. 2325ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov volatile int32_t num_pending_readers_; 2335ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov // Pending writers. 2345ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov volatile int32_t num_pending_writers_; 2355ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov#else 236517d9f6678c5d577f25777bc000a83afd5503874Artem Serov pthread_rwlock_t rwlock_; 2375ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov#endif 2385ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov friend class MutexTester; 2395ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov DISALLOW_COPY_AND_ASSIGN(ReaderWriterMutex); 2405ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov}; 2415ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 2425ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// ConditionVariables allow threads to queue and sleep. Threads may then be resumed individually 2435ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// (Signal) or all at once (Broadcast). 2445ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilovclass ConditionVariable { 2455ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov public: 2465ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov explicit ConditionVariable(const std::string& name); 2475ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov ~ConditionVariable(); 2485ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 249ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko void Broadcast(); 250331605a7ba842573b3876e14c933175382b923c8Nicolas Geoffray void Signal(); 2515ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void Wait(Thread* self, Mutex& mutex); 2525ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov void TimedWait(Thread* self, Mutex& mutex, const timespec& ts); 2535ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 2545ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov private: 2555ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov pthread_cond_t cond_; 2565ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov std::string name_; 2575ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov DISALLOW_COPY_AND_ASSIGN(ConditionVariable); 2585ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov}; 2595ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 2605ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// Scoped locker/unlocker for a regular Mutex that acquires mu upon construction and releases it 2615ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// upon destruction. 2625ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilovclass SCOPED_LOCKABLE MutexLock { 263ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko public: 264ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko explicit MutexLock(Thread* self, Mutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : self_(self), mu_(mu) { 265ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko mu_.ExclusiveLock(self_); 2665ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 2675ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 2685ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov explicit MutexLock(Mutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : self_(Thread::Current()), mu_(mu) { 2695ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov mu_.ExclusiveLock(self_); 270ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko } 271ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 272ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko ~MutexLock() UNLOCK_FUNCTION() { 2735ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov mu_.ExclusiveUnlock(self_); 2745ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 2755ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 2765ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov private: 2775ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov Thread* const self_; 2785ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov Mutex& mu_; 2795ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov DISALLOW_COPY_AND_ASSIGN(MutexLock); 2805ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov}; 2815ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// Catch bug where variable name is omitted. "MutexLock (lock);" instead of "MutexLock mu(lock)". 2825ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_declaration_missing_variable_name) 2835ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 2845ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// Scoped locker/unlocker for a ReaderWriterMutex that acquires read access to mu upon 2855ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// construction and releases it upon destruction. 2865ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilovclass SCOPED_LOCKABLE ReaderMutexLock { 2875ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov public: 2885ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov explicit ReaderMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : 2895ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov self_(self), mu_(mu) { 2905ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov mu_.SharedLock(self_); 2915ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 2925ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 2935ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov explicit ReaderMutexLock(ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : 2945ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov self_(Thread::Current()), mu_(mu) { 2955ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov mu_.SharedLock(self_); 2965ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 2975ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 298ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko ~ReaderMutexLock() UNLOCK_FUNCTION() { 2995ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov mu_.SharedUnlock(self_); 3005ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 301ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 3025ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov private: 3035ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov Thread* const self_; 3045ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov ReaderWriterMutex& mu_; 3055ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov DISALLOW_COPY_AND_ASSIGN(ReaderMutexLock); 3065ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov}; 3075ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// Catch bug where variable name is omitted. "ReaderMutexLock (lock);" instead of 3085ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// "ReaderMutexLock mu(lock)". 3095ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov#define ReaderMutexLock(x) COMPILE_ASSERT(0, reader_mutex_lock_declaration_missing_variable_name) 3105ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 3115ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov// Scoped locker/unlocker for a ReaderWriterMutex that acquires write access to mu upon 312ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko// construction and releases it upon destruction. 3135ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilovclass SCOPED_LOCKABLE WriterMutexLock { 3145ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov public: 315ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko explicit WriterMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : 3165ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov self_(self), mu_(mu) { 3175ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov mu_.ExclusiveLock(self_); 3185ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 3195ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 3205ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov explicit WriterMutexLock(ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : 3215ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov self_(Thread::Current()), mu_(mu) { 3225ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov mu_.ExclusiveLock(self_); 3235ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov } 3245ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 325ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko ~WriterMutexLock() UNLOCK_FUNCTION() { 326ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko mu_.ExclusiveUnlock(self_); 327ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko } 3285ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov 3295ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov private: 3305ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov Thread* self_; 3315ec621870ebacca414a5f8114f620854e9ab2948Anton Kirilov ReaderWriterMutex& mu_; 332ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DISALLOW_COPY_AND_ASSIGN(WriterMutexLock); 333ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko}; 334ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko// Catch bug where variable name is omitted. "WriterMutexLock (lock);" instead of 33527292e64b312007cd301fed8aa96ed7c0215b231Petre-Ionut Tudor// "WriterMutexLock mu(lock)". 33627292e64b312007cd301fed8aa96ed7c0215b231Petre-Ionut Tudor#define WriterMutexLock(x) COMPILE_ASSERT(0, writer_mutex_lock_declaration_missing_variable_name) 33727292e64b312007cd301fed8aa96ed7c0215b231Petre-Ionut Tudor 33827292e64b312007cd301fed8aa96ed7c0215b231Petre-Ionut Tudor} // namespace art 339ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 340ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko#endif // ART_SRC_MUTEX_H_ 341ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko