ttas_spin_lock.cpp 1.16 KB
Newer Older
FritzFlorian committed
1 2
#include "pls/internal/helpers/profiler.h"
#include "pls/internal/base/ttas_spin_lock.h"
3
#include "pls/internal/base/backoff.h"
FritzFlorian committed
4 5

namespace pls {
6 7 8 9 10 11
namespace internal {
namespace base {

void ttas_spin_lock::lock() {
  PROFILE_LOCK("Acquire Lock")
  int expected = 0;
12
  backoff backoff_;
13

14
  while (true) {
15 16
    while (flag_.load(std::memory_order_relaxed) == 1)
      system_details::relax_cpu(); // Spin
17 18

    expected = 0;
19 20 21
    if (flag_.compare_exchange_weak(expected, 1, std::memory_order_acquire)) {
      return;
    }
22
    backoff_.do_backoff();
23
  }
24 25 26 27 28
}

bool ttas_spin_lock::try_lock(unsigned int num_tries) {
  PROFILE_LOCK("Try Acquire Lock")
  int expected = 0;
29
  backoff backoff_;
30

31
  while (true) {
32
    while (flag_.load() == 1) {
33 34 35 36
      num_tries--;
      if (num_tries <= 0) {
        return false;
      }
37
      system_details::relax_cpu();
38 39 40
    }

    expected = 0;
41 42 43
    if (flag_.compare_exchange_weak(expected, 1, std::memory_order_acquire)) {
      return true;
    }
44 45 46 47 48
    num_tries--;
    if (num_tries <= 0) {
      return false;
    }
    backoff_.do_backoff();
49
  }
50 51 52
}

void ttas_spin_lock::unlock() {
53
  PROFILE_LOCK("Unlock")
54 55 56 57 58
  flag_.store(0, std::memory_order_release);
}

}
}
FritzFlorian committed
59
}