forked from OSchip/llvm-project
sanitizer_common: modernize SpinMutex
Some minor improvements: 1. Make StaticSpinMutex non-copyable. 2. Add LIKELY to Lock. 3. Move LockSlow into the .cpp file (now that we have it). 4. The only non-trivial change: use proc_yield(1) instread of proc_yield(10) with the proportional increase in the number of spin iterations. Latency of the PAUSE instruction has raised from ~1 cycle to ~100 cycles in the recent Intel CPUs. So proc_yield(10) is too aggressive backoff. Reviewed By: vitalybuka Differential Revision: https://reviews.llvm.org/D106350
This commit is contained in:
parent
9226e6f7d2
commit
927efd0b5d
|
@ -16,6 +16,18 @@
|
|||
|
||||
namespace __sanitizer {
|
||||
|
||||
void StaticSpinMutex::LockSlow() {
|
||||
for (int i = 0;; i++) {
|
||||
if (i < 100)
|
||||
proc_yield(1);
|
||||
else
|
||||
internal_sched_yield();
|
||||
if (atomic_load(&state_, memory_order_relaxed) == 0 &&
|
||||
atomic_exchange(&state_, 1, memory_order_acquire) == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Semaphore::Wait() {
|
||||
u32 count = atomic_load(&state_, memory_order_relaxed);
|
||||
for (;;) {
|
||||
|
|
|
@ -22,12 +22,14 @@ namespace __sanitizer {
|
|||
|
||||
class MUTEX StaticSpinMutex {
|
||||
public:
|
||||
StaticSpinMutex() = default;
|
||||
|
||||
void Init() {
|
||||
atomic_store(&state_, 0, memory_order_relaxed);
|
||||
}
|
||||
|
||||
void Lock() ACQUIRE() {
|
||||
if (TryLock())
|
||||
if (LIKELY(TryLock()))
|
||||
return;
|
||||
LockSlow();
|
||||
}
|
||||
|
@ -45,17 +47,10 @@ class MUTEX StaticSpinMutex {
|
|||
private:
|
||||
atomic_uint8_t state_;
|
||||
|
||||
void NOINLINE LockSlow() {
|
||||
for (int i = 0;; i++) {
|
||||
if (i < 10)
|
||||
proc_yield(10);
|
||||
else
|
||||
internal_sched_yield();
|
||||
if (atomic_load(&state_, memory_order_relaxed) == 0
|
||||
&& atomic_exchange(&state_, 1, memory_order_acquire) == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
void LockSlow();
|
||||
|
||||
StaticSpinMutex(const StaticSpinMutex &) = delete;
|
||||
void operator=(const StaticSpinMutex &) = delete;
|
||||
};
|
||||
|
||||
class MUTEX SpinMutex : public StaticSpinMutex {
|
||||
|
@ -63,10 +58,6 @@ class MUTEX SpinMutex : public StaticSpinMutex {
|
|||
SpinMutex() {
|
||||
Init();
|
||||
}
|
||||
|
||||
private:
|
||||
SpinMutex(const SpinMutex &) = delete;
|
||||
void operator=(const SpinMutex &) = delete;
|
||||
};
|
||||
|
||||
// Semaphore provides an OS-dependent way to park/unpark threads.
|
||||
|
|
Loading…
Reference in New Issue