mutex.h revision 5bd97c483c1de1eb97afe76123b1b9ab53095edf
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"
2850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers#include "logging.h"
298daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include "macros.h"
3081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers
31ab47016374d340011680e9cd970ee7d6225d6704Ian Rogers#if defined(__APPLE__)
3281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers#define ART_USE_FUTEXES 0
33ab47016374d340011680e9cd970ee7d6225d6704Ian Rogers#else
345bd97c483c1de1eb97afe76123b1b9ab53095edfIan 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
4650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogersclass Thread;
4750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers
4825fd14b87cced64a179dee885573113be5e11944Ian Rogersconst bool kDebugLocking = kIsDebugBuild;
4925fd14b87cced64a179dee885573113be5e11944Ian Rogers
5000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Base class for all Mutex implementations
5100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersclass BaseMutex {
5200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers public:
5300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  const std::string& GetName() const {
5400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return name_;
5500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
5600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
5700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  virtual bool IsMutex() const { return false; }
5800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  virtual bool IsReaderWriterMutex() const { return false; }
5900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
6000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers protected:
6100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  friend class ConditionVariable;
6200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
6381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  BaseMutex(const char* name, LockLevel level);
6400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  virtual ~BaseMutex() {}
6581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void RegisterAsLocked(Thread* self);
6681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void RegisterAsUnlocked(Thread* self);
6781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void CheckSafeToWait(Thread* self);
6800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
6981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  const LockLevel level_;  // Support for lock hierarchy.
700a1038b0a30a52dff1a449a989825e808a83df80Elliott Hughes  const std::string name_;
7100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers};
7200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
7300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// A Mutex is used to achieve mutual exclusion between threads. A Mutex can be used to gain
7400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// exclusive access to what it guards. A Mutex can be in one of two states:
7500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// - Free - not owned by any thread,
7600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// - Exclusive - owned by a single thread.
7700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers//
7800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// The effect of locking and unlocking operations on the state is:
7900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// State     | ExclusiveLock | ExclusiveUnlock
8000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// -------------------------------------------
8100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Free      | Exclusive     | error
8200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Exclusive | Block*        | Free
8300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// * Mutex is not reentrant and so an attempt to ExclusiveLock on the same thread will result in
8400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers//   an error. Being non-reentrant simplifies Waiting on ConditionVariables.
8501ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogersstd::ostream& operator<<(std::ostream& os, const Mutex& mu);
8600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersclass LOCKABLE Mutex : public BaseMutex {
8700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers public:
8881d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  explicit Mutex(const char* name, LockLevel level = kDefaultMutexLevel, bool recursive = false);
8900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ~Mutex();
9000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
9100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  virtual bool IsMutex() const { return true; }
9200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
9300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Block until mutex is free then acquire exclusive access.
9481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void ExclusiveLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION();
9581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void Lock(Thread* self) EXCLUSIVE_LOCK_FUNCTION() {  ExclusiveLock(self); }
9600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
9700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Returns true if acquires exclusive access, false otherwise.
9881d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  bool ExclusiveTryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true);
9981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  bool TryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true) { return ExclusiveTryLock(self); }
10000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
10100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Release exclusive access.
10281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void ExclusiveUnlock(Thread* self) UNLOCK_FUNCTION();
10381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void Unlock(Thread* self) UNLOCK_FUNCTION() {  ExclusiveUnlock(self); }
10400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
10500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Is the current thread the exclusive holder of the Mutex.
10681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  bool IsExclusiveHeld(const Thread* self) const;
1078daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
10800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Assert that the Mutex is exclusively held by the current thread.
10981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void AssertExclusiveHeld(const Thread* self) {
11081b8871007101f42e2baabf213e1312004073eb0Brian Carlstrom    if (kDebugLocking && !gAborting) {
11101ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers      CHECK(IsExclusiveHeld(self)) << *this;
11200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
11300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
11481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void AssertHeld(const Thread* self) { AssertExclusiveHeld(self); }
11500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
11600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Assert that the Mutex is not held by the current thread.
11781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void AssertNotHeldExclusive(const Thread* self) {
11825fd14b87cced64a179dee885573113be5e11944Ian Rogers    if (kDebugLocking) {
11901ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers      CHECK(!IsExclusiveHeld(self)) << *this;
12000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
12100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
12281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void AssertNotHeld(const Thread* self) { AssertNotHeldExclusive(self); }
12300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
12400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Id associated with exclusive owner.
12500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  uint64_t GetExclusiveOwnerTid() const;
12600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
12700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Returns how many times this Mutex has been locked, it is better to use AssertHeld/NotHeld.
12800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  unsigned int GetDepth() const {
12900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return recursion_count_;
13000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
13100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
13201ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers  std::string Dump() const;
13301ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers
13400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers private:
135c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers#if ART_USE_FUTEXES
136c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  // 0 is unheld, 1 is held.
137c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  volatile int32_t state_;
138c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  // Exclusive owner.
139c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  volatile uint64_t exclusive_owner_;
140c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  // Number of waiting contenders.
141c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  volatile int32_t num_contenders_;
142c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers#else
14300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  pthread_mutex_t mutex_;
144c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers#endif
14500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  const bool recursive_;  // Can the lock be recursively held?
14600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  unsigned int recursion_count_;
147f1498437b0d6beb9f4f91980b98cbeb0b5c773ceElliott Hughes  friend class ConditionVariable;
1483efb8416c9809a1da3300509fd9d2bc54e22e4c2Elliott Hughes  friend class MutexTester;
1498daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  DISALLOW_COPY_AND_ASSIGN(Mutex);
1508daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes};
1518daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
15200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// A ReaderWriterMutex is used to achieve mutual exclusion between threads, similar to a Mutex.
15300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Unlike a Mutex a ReaderWriterMutex can be used to gain exclusive (writer) or shared (reader)
15400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// access to what it guards. A flaw in relation to a Mutex is that it cannot be used with a
15500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// condition variable. A ReaderWriterMutex can be in one of three states:
15600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// - Free - not owned by any thread,
15700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// - Exclusive - owned by a single thread,
15800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// - Shared(n) - shared amongst n threads.
15900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers//
16000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// The effect of locking and unlocking operations on the state is:
16100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers//
16200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// State     | ExclusiveLock | ExclusiveUnlock | SharedLock       | SharedUnlock
16300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// ----------------------------------------------------------------------------
16400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Free      | Exclusive     | error           | SharedLock(1)    | error
16500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Exclusive | Block         | Free            | Block            | error
16600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Shared(n) | Block         | error           | SharedLock(n+1)* | Shared(n-1) or Free
16700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// * for large values of n the SharedLock may block.
16801ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogersstd::ostream& operator<<(std::ostream& os, const ReaderWriterMutex& mu);
16900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersclass LOCKABLE ReaderWriterMutex : public BaseMutex {
1708daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes public:
17181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  explicit ReaderWriterMutex(const char* name, LockLevel level = kDefaultMutexLevel);
17200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ~ReaderWriterMutex();
17300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
17400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  virtual bool IsReaderWriterMutex() const { return true; }
17500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
17600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Block until ReaderWriterMutex is free then acquire exclusive access.
17781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void ExclusiveLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION();
17881d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void WriterLock(Thread* self) EXCLUSIVE_LOCK_FUNCTION() {  ExclusiveLock(self); }
17900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
18000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Release exclusive access.
18181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void ExclusiveUnlock(Thread* self) UNLOCK_FUNCTION();
18281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void WriterUnlock(Thread* self) UNLOCK_FUNCTION() {  ExclusiveUnlock(self); }
18300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
18400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Block until ReaderWriterMutex is free and acquire exclusive access. Returns true on success
18500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // or false if timeout is reached.
18666aee5cd571cf4739d2735769304202ea5051fb8Ian Rogers#if HAVE_TIMED_RWLOCK
187c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  bool ExclusiveLockWithTimeout(Thread* self, int64_t ms, int32_t ns)
18881d425b0b232962441616f8b14f73620bffef5e5Ian Rogers      EXCLUSIVE_TRYLOCK_FUNCTION(true);
18966aee5cd571cf4739d2735769304202ea5051fb8Ian Rogers#endif
19000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
19100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Block until ReaderWriterMutex is shared or free then acquire a share on the access.
19281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void SharedLock(Thread* self) SHARED_LOCK_FUNCTION();
19381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void ReaderLock(Thread* self) SHARED_LOCK_FUNCTION() { SharedLock(self); }
19400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
19500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Try to acquire share of ReaderWriterMutex.
19681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  bool SharedTryLock(Thread* self) EXCLUSIVE_TRYLOCK_FUNCTION(true);
19700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
19800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Release a share of the access.
19981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void SharedUnlock(Thread* self) UNLOCK_FUNCTION();
20081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void ReaderUnlock(Thread* self) UNLOCK_FUNCTION() { SharedUnlock(self); }
20100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
20200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Is the current thread the exclusive holder of the ReaderWriterMutex.
20381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  bool IsExclusiveHeld(const Thread* self) const;
20400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
20500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Assert the current thread has exclusive access to the ReaderWriterMutex.
20681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void AssertExclusiveHeld(const Thread* self) {
20725fd14b87cced64a179dee885573113be5e11944Ian Rogers    if (kDebugLocking) {
20801ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers      CHECK(IsExclusiveHeld(self)) << *this;
20900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
2108daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
21181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void AssertWriterHeld(const Thread* self) { AssertExclusiveHeld(self); }
2128daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
21300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Assert the current thread doesn't have exclusive access to the ReaderWriterMutex.
21481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void AssertNotExclusiveHeld(const Thread* self) {
21525fd14b87cced64a179dee885573113be5e11944Ian Rogers    if (kDebugLocking) {
21681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers      CHECK(!IsExclusiveHeld(self));
21700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
21800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
21981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void AssertNotWriterHeld(const Thread* self) { AssertNotExclusiveHeld(self); }
22000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
22100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Is the current thread a shared holder of the ReaderWriterMutex.
22281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  bool IsSharedHeld(const Thread* self) const;
22300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
22400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Assert the current thread has shared access to the ReaderWriterMutex.
22581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void AssertSharedHeld(const Thread* self) {
22625fd14b87cced64a179dee885573113be5e11944Ian Rogers    if (kDebugLocking) {
22701ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers      CHECK(IsSharedHeld(self)) << *this;
22800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
2298daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
23081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void AssertReaderHeld(const Thread* self) { AssertSharedHeld(self); }
2318daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
23200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Assert the current thread doesn't hold this ReaderWriterMutex either in shared or exclusive
23300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // mode.
23481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void AssertNotHeld(const Thread* self) {
23525fd14b87cced64a179dee885573113be5e11944Ian Rogers    if (kDebugLocking) {
23601ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers      CHECK(!IsSharedHeld(self)) << *this;
23700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
23800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
23900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
24000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Id associated with exclusive owner.
24100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  uint64_t GetExclusiveOwnerTid() const;
24281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers
24301ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers  std::string Dump() const;
24401ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers
2458daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes private:
24681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers#if ART_USE_FUTEXES
24781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  // -1 implies held exclusive, +ve shared held by state_ many owners.
24881d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  volatile int32_t state_;
24981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  // Exclusive owner.
25081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  volatile uint64_t exclusive_owner_;
25181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  // Pending readers.
25281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  volatile int32_t num_pending_readers_;
25381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  // Pending writers.
25481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  volatile int32_t num_pending_writers_;
25581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers#else
25600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  pthread_rwlock_t rwlock_;
25781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers#endif
25800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  friend class MutexTester;
25900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  DISALLOW_COPY_AND_ASSIGN(ReaderWriterMutex);
2608daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes};
2618daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
26200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// ConditionVariables allow threads to queue and sleep. Threads may then be resumed individually
26300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// (Signal) or all at once (Broadcast).
2645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesclass ConditionVariable {
2655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes public:
266c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  explicit ConditionVariable(const std::string& name, Mutex& mutex);
2675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  ~ConditionVariable();
2685f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
269c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  void Broadcast(Thread* self);
270c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  void Signal(Thread* self);
271c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  // TODO: No thread safety analysis on Wait and TimedWait as they call mutex operations via their
272c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  //       pointer copy, thereby defeating annotalysis.
273c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  void Wait(Thread* self) NO_THREAD_SAFETY_ANALYSIS;
274c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  void TimedWait(Thread* self, int64_t ms, int32_t ns) NO_THREAD_SAFETY_ANALYSIS;
2755f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
2765f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes private:
2775f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  std::string name_;
278c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  // The Mutex being used by waiters. It is an error to mix condition variables between different
279c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  // Mutexes.
280c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  Mutex& guard_;
281c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers#if ART_USE_FUTEXES
282c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  // A counter that is modified by signals and broadcasts. This ensures that when a waiter gives up
283c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  // their Mutex and another thread takes it and signals, the waiting thread observes that state_
284c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  // changed and doesn't enter the wait.
285c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  volatile int32_t state_;
286c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  // Number of threads that have come into to wait, not the length of the waiters on the futex as
2875bd97c483c1de1eb97afe76123b1b9ab53095edfIan Rogers  // waiters may have been requeued onto guard_. Guarded by guard_.
288c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  volatile int32_t num_waiters_;
2895bd97c483c1de1eb97afe76123b1b9ab53095edfIan Rogers  // Number of threads that have been awoken out of the pool of waiters. Guarded by guard_.
290c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  volatile int32_t num_awoken_;
291c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers#else
292c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  pthread_cond_t cond_;
293c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers#endif
2945f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DISALLOW_COPY_AND_ASSIGN(ConditionVariable);
2955f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes};
2965f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
29700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Scoped locker/unlocker for a regular Mutex that acquires mu upon construction and releases it
29800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// upon destruction.
29900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersclass SCOPED_LOCKABLE MutexLock {
30000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers public:
30181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  explicit MutexLock(Thread* self, Mutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : self_(self), mu_(mu) {
30281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers    mu_.ExclusiveLock(self_);
30381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  }
30481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers
30500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ~MutexLock() UNLOCK_FUNCTION() {
30681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers    mu_.ExclusiveUnlock(self_);
30700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
30800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
30900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers private:
31081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  Thread* const self_;
31100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Mutex& mu_;
31200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  DISALLOW_COPY_AND_ASSIGN(MutexLock);
31300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers};
31400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Catch bug where variable name is omitted. "MutexLock (lock);" instead of "MutexLock mu(lock)".
31500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_declaration_missing_variable_name)
31600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
31700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Scoped locker/unlocker for a ReaderWriterMutex that acquires read access to mu upon
31800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// construction and releases it upon destruction.
31900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersclass SCOPED_LOCKABLE ReaderMutexLock {
32000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers public:
32181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  explicit ReaderMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
32281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers      self_(self), mu_(mu) {
32381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers    mu_.SharedLock(self_);
32481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  }
32581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers
32600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ~ReaderMutexLock() UNLOCK_FUNCTION() {
32781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers    mu_.SharedUnlock(self_);
32800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
32900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
33000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers private:
33181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  Thread* const self_;
33200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ReaderWriterMutex& mu_;
33300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  DISALLOW_COPY_AND_ASSIGN(ReaderMutexLock);
33400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers};
33500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Catch bug where variable name is omitted. "ReaderMutexLock (lock);" instead of
33600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// "ReaderMutexLock mu(lock)".
33700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#define ReaderMutexLock(x) COMPILE_ASSERT(0, reader_mutex_lock_declaration_missing_variable_name)
33800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
33900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Scoped locker/unlocker for a ReaderWriterMutex that acquires write access to mu upon
34000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// construction and releases it upon destruction.
34100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersclass SCOPED_LOCKABLE WriterMutexLock {
34200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers public:
34381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  explicit WriterMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
34481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers      self_(self), mu_(mu) {
34581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers    mu_.ExclusiveLock(self_);
34681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  }
34781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers
34800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ~WriterMutexLock() UNLOCK_FUNCTION() {
34981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers    mu_.ExclusiveUnlock(self_);
35000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
35100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
35200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers private:
35350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  Thread* const self_;
35400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ReaderWriterMutex& mu_;
35500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  DISALLOW_COPY_AND_ASSIGN(WriterMutexLock);
35600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers};
35700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Catch bug where variable name is omitted. "WriterMutexLock (lock);" instead of
35800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// "WriterMutexLock mu(lock)".
35900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#define WriterMutexLock(x) COMPILE_ASSERT(0, writer_mutex_lock_declaration_missing_variable_name)
36000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
3618daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes}  // namespace art
3628daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
3638daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#endif  // ART_SRC_MUTEX_H_
364