regex_constants.h: Add underlying `unsigned int` for enum syntax_option_type.
[official-gcc.git] / libsanitizer / sanitizer_common / sanitizer_mutex.h
blob27009118e62fb9b9611106ce249811ed023a388c
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 private:
42 atomic_uint8_t state_;
44 void NOINLINE LockSlow() {
45 for (int i = 0;; i++) {
46 if (i < 10)
47 proc_yield(10);
48 else
49 internal_sched_yield();
50 if (atomic_load(&state_, memory_order_relaxed) == 0
51 && atomic_exchange(&state_, 1, memory_order_acquire) == 0)
52 return;
57 class SpinMutex : public StaticSpinMutex {
58 public:
59 SpinMutex() {
60 Init();
63 private:
64 SpinMutex(const SpinMutex&);
65 void operator=(const SpinMutex&);
68 class BlockingMutex {
69 public:
70 explicit BlockingMutex(LinkerInitialized);
71 void Lock();
72 void Unlock();
73 private:
74 uptr opaque_storage_[10];
75 uptr owner_; // for debugging
78 template<typename MutexType>
79 class GenericScopedLock {
80 public:
81 explicit GenericScopedLock(MutexType *mu)
82 : mu_(mu) {
83 mu_->Lock();
86 ~GenericScopedLock() {
87 mu_->Unlock();
90 private:
91 MutexType *mu_;
93 GenericScopedLock(const GenericScopedLock&);
94 void operator=(const GenericScopedLock&);
97 template<typename MutexType>
98 class GenericScopedReadLock {
99 public:
100 explicit GenericScopedReadLock(MutexType *mu)
101 : mu_(mu) {
102 mu_->ReadLock();
105 ~GenericScopedReadLock() {
106 mu_->ReadUnlock();
109 private:
110 MutexType *mu_;
112 GenericScopedReadLock(const GenericScopedReadLock&);
113 void operator=(const GenericScopedReadLock&);
116 typedef GenericScopedLock<StaticSpinMutex> SpinMutexLock;
117 typedef GenericScopedLock<BlockingMutex> BlockingMutexLock;
119 } // namespace __sanitizer
121 #endif // SANITIZER_MUTEX_H