123456789101112131415161718192021222324252627282930313233343536373839 |
- #include "spin_wait.h"
- #include "yield.h"
- #include "compat.h"
- #include "spinlock.h"
- #include <util/digest/numeric.h>
- #include <util/generic/utility.h>
- template <class T>
- static inline T RandomizeSleepTime(T t) noexcept {
- static TAtomic counter = 0;
- const T rndNum = IntHash((T)AtomicIncrement(counter));
- return (t * (T)4 + (rndNum % t) * (T)2) / (T)5;
- }
- //arbitrary values
- #define MIN_SLEEP_TIME 500
- #define MAX_SPIN_COUNT 0x7FF
- 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();
- }
- }
|