#include "spin_wait.h" #include "yield.h" #include "compat.h" #include "spinlock.h" #include #include #include namespace { unsigned RandomizeSleepTime(unsigned t) noexcept { static std::atomic counter = 0; const unsigned rndNum = IntHash(++counter); return (t * 4 + (rndNum % t) * 2) / 5; } // arbitrary values constexpr unsigned MIN_SLEEP_TIME = 500; constexpr unsigned MAX_SPIN_COUNT = 0x7FF; } // namespace TSpinWait::TSpinWait() noexcept : T(MIN_SLEEP_TIME) , C(0) { } void TSpinWait::Sleep() noexcept { ++C; if (C == MAX_SPIN_COUNT) { ThreadYield(); } else if ((C & MAX_SPIN_COUNT) == 0) { usleep(RandomizeSleepTime(T)); T = Min(T * 3 / 2, 20000); } else { SpinLockPause(); } }