Daily bump.
[official-gcc.git] / libsanitizer / sanitizer_common / sanitizer_mutex.h
blobd78f43edaaed2c05bfc0998631ff9e2cef0ba3d6
1 //===-- sanitizer_mutex.h ---------------------------------------*- C++ -*-===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is a part of ThreadSanitizer/AddressSanitizer runtime.
9 //
10 //===----------------------------------------------------------------------===//
12 #ifndef SANITIZER_MUTEX_H
13 #define SANITIZER_MUTEX_H
15 #include "sanitizer_atomic.h"
16 #include "sanitizer_internal_defs.h"
17 #include "sanitizer_libc.h"
19 namespace __sanitizer {
21 class StaticSpinMutex {
22 public:
23 void Init() {
24 atomic_store(&state_, 0, memory_order_relaxed);
27 void Lock() {
28 if (TryLock())
29 return;
30 LockSlow();
33 bool TryLock() {
34 return atomic_exchange(&state_, 1, memory_order_acquire) == 0;
37 void Unlock() {
38 atomic_store(&state_, 0, memory_order_release);
41 void CheckLocked() {
42 CHECK_EQ(atomic_load(&state_, memory_order_relaxed), 1);
45 private:
46 atomic_uint8_t state_;
48 void NOINLINE LockSlow() {
49 for (int i = 0;; i++) {
50 if (i < 10)
51 proc_yield(10);
52 else
53 internal_sched_yield();
54 if (atomic_load(&state_, memory_order_relaxed) == 0
55 && atomic_exchange(&state_, 1, memory_order_acquire) == 0)
56 return;
61 class SpinMutex : public StaticSpinMutex {
62 public:
63 SpinMutex() {
64 Init();
67 private:
68 SpinMutex(const SpinMutex&);
69 void operator=(const SpinMutex&);
72 class BlockingMutex {
73 public:
74 explicit BlockingMutex(LinkerInitialized);
75 BlockingMutex();
76 void Lock();
77 void Unlock();
78 void CheckLocked();
79 private:
80 uptr opaque_storage_[10];
81 uptr owner_; // for debugging
84 template<typename MutexType>
85 class GenericScopedLock {
86 public:
87 explicit GenericScopedLock(MutexType *mu)
88 : mu_(mu) {
89 mu_->Lock();
92 ~GenericScopedLock() {
93 mu_->Unlock();
96 private:
97 MutexType *mu_;
99 GenericScopedLock(const GenericScopedLock&);
100 void operator=(const GenericScopedLock&);
103 template<typename MutexType>
104 class GenericScopedReadLock {
105 public:
106 explicit GenericScopedReadLock(MutexType *mu)
107 : mu_(mu) {
108 mu_->ReadLock();
111 ~GenericScopedReadLock() {
112 mu_->ReadUnlock();
115 private:
116 MutexType *mu_;
118 GenericScopedReadLock(const GenericScopedReadLock&);
119 void operator=(const GenericScopedReadLock&);
122 typedef GenericScopedLock<StaticSpinMutex> SpinMutexLock;
123 typedef GenericScopedLock<BlockingMutex> BlockingMutexLock;
125 } // namespace __sanitizer
127 #endif // SANITIZER_MUTEX_H