]>
git.ipfire.org Git - thirdparty/gcc.git/blob - libsanitizer/sanitizer_common/sanitizer_mutex.h
1 //===-- sanitizer_mutex.h ---------------------------------------*- C++ -*-===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is a part of ThreadSanitizer/AddressSanitizer runtime.
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
{
24 atomic_store(&state_
, 0, memory_order_relaxed
);
34 return atomic_exchange(&state_
, 1, memory_order_acquire
) == 0;
38 atomic_store(&state_
, 0, memory_order_release
);
42 CHECK_EQ(atomic_load(&state_
, memory_order_relaxed
), 1);
46 atomic_uint8_t state_
;
48 void NOINLINE
LockSlow() {
49 for (int i
= 0;; i
++) {
53 internal_sched_yield();
54 if (atomic_load(&state_
, memory_order_relaxed
) == 0
55 && atomic_exchange(&state_
, 1, memory_order_acquire
) == 0)
61 class SpinMutex
: public StaticSpinMutex
{
68 SpinMutex(const SpinMutex
&);
69 void operator=(const SpinMutex
&);
74 explicit constexpr BlockingMutex(LinkerInitialized
)
75 : opaque_storage_
{0, }, owner_
{0} {}
80 // This function does not guarantee an explicit check that the calling thread
81 // is the thread which owns the mutex. This behavior, while more strictly
82 // correct, causes problems in cases like StopTheWorld, where a parent thread
83 // owns the mutex but a child checks that it is locked. Rather than
84 // maintaining complex state to work around those situations, the check only
85 // checks that the mutex is owned, and assumes callers to be generally
90 // Solaris mutex_t has a member that requires 64-bit alignment.
91 ALIGNED(8) uptr opaque_storage_
[10];
92 uptr owner_
; // for debugging
95 // Reader-writer spin mutex.
99 atomic_store(&state_
, kUnlocked
, memory_order_relaxed
);
103 CHECK_EQ(atomic_load(&state_
, memory_order_relaxed
), kUnlocked
);
108 if (atomic_compare_exchange_strong(&state_
, &cmp
, kWriteLock
,
109 memory_order_acquire
))
115 u32 prev
= atomic_fetch_sub(&state_
, kWriteLock
, memory_order_release
);
116 DCHECK_NE(prev
& kWriteLock
, 0);
121 u32 prev
= atomic_fetch_add(&state_
, kReadLock
, memory_order_acquire
);
122 if ((prev
& kWriteLock
) == 0)
128 u32 prev
= atomic_fetch_sub(&state_
, kReadLock
, memory_order_release
);
129 DCHECK_EQ(prev
& kWriteLock
, 0);
130 DCHECK_GT(prev
& ~kWriteLock
, 0);
135 CHECK_NE(atomic_load(&state_
, memory_order_relaxed
), kUnlocked
);
139 atomic_uint32_t state_
;
147 void NOINLINE
LockSlow() {
148 for (int i
= 0;; i
++) {
152 internal_sched_yield();
153 u32 cmp
= atomic_load(&state_
, memory_order_relaxed
);
154 if (cmp
== kUnlocked
&&
155 atomic_compare_exchange_weak(&state_
, &cmp
, kWriteLock
,
156 memory_order_acquire
))
161 void NOINLINE
ReadLockSlow() {
162 for (int i
= 0;; i
++) {
166 internal_sched_yield();
167 u32 prev
= atomic_load(&state_
, memory_order_acquire
);
168 if ((prev
& kWriteLock
) == 0)
173 RWMutex(const RWMutex
&);
174 void operator = (const RWMutex
&);
177 template<typename MutexType
>
178 class GenericScopedLock
{
180 explicit GenericScopedLock(MutexType
*mu
)
185 ~GenericScopedLock() {
192 GenericScopedLock(const GenericScopedLock
&);
193 void operator=(const GenericScopedLock
&);
196 template<typename MutexType
>
197 class GenericScopedReadLock
{
199 explicit GenericScopedReadLock(MutexType
*mu
)
204 ~GenericScopedReadLock() {
211 GenericScopedReadLock(const GenericScopedReadLock
&);
212 void operator=(const GenericScopedReadLock
&);
215 typedef GenericScopedLock
<StaticSpinMutex
> SpinMutexLock
;
216 typedef GenericScopedLock
<BlockingMutex
> BlockingMutexLock
;
217 typedef GenericScopedLock
<RWMutex
> RWMutexLock
;
218 typedef GenericScopedReadLock
<RWMutex
> RWMutexReadLock
;
220 } // namespace __sanitizer
222 #endif // SANITIZER_MUTEX_H