123456789101112131415161718192021222324252627282930313233343536373839404142 |
- #include "spin_wait.h"
- #include "yield.h"
- #include "compat.h"
- #include "spinlock.h"
- #include <util/digest/numeric.h>
- #include <util/generic/utility.h>
- #include <atomic>
- namespace {
- unsigned RandomizeSleepTime(unsigned t) noexcept {
- static std::atomic<unsigned> 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<unsigned>(T * 3 / 2, 20000);
- } else {
- SpinLockPause();
- }
- }
|