spin_wait.cpp 794 B

123456789101112131415161718192021222324252627282930313233343536373839
  1. #include "spin_wait.h"
  2. #include "yield.h"
  3. #include "compat.h"
  4. #include "spinlock.h"
  5. #include <util/digest/numeric.h>
  6. #include <util/generic/utility.h>
  7. template <class T>
  8. static inline T RandomizeSleepTime(T t) noexcept {
  9. static TAtomic counter = 0;
  10. const T rndNum = IntHash((T)AtomicIncrement(counter));
  11. return (t * (T)4 + (rndNum % t) * (T)2) / (T)5;
  12. }
  13. //arbitrary values
  14. #define MIN_SLEEP_TIME 500
  15. #define MAX_SPIN_COUNT 0x7FF
  16. TSpinWait::TSpinWait() noexcept
  17. : T(MIN_SLEEP_TIME)
  18. , C(0)
  19. {
  20. }
  21. void TSpinWait::Sleep() noexcept {
  22. ++C;
  23. if (C == MAX_SPIN_COUNT) {
  24. ThreadYield();
  25. } else if ((C & MAX_SPIN_COUNT) == 0) {
  26. usleep(RandomizeSleepTime(T));
  27. T = Min<unsigned>((T * 3) / 2, 20000);
  28. } else {
  29. SpinLockPause();
  30. }
  31. }