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