swmr_spin_lock.cpp 974 Bytes
Newer Older
1 2 3 4 5 6 7 8
#include "pls/internal/base/swmr_spin_lock.h"
#include "pls/internal/base/system_details.h"

namespace pls {
namespace internal {
namespace base {

bool swmr_spin_lock::reader_try_lock() {
9
  if (write_request_.load(std::memory_order_acquire) == 1) {
10 11 12
    return false;
  }
  // We think we can enter the region
13
  readers_.fetch_add(1, std::memory_order_acquire);
14
  if (write_request_.load(std::memory_order_acquire) == 1) {
15
    // Whoops, the writer acquires the lock, so we back off again
16
    readers_.fetch_add(-1, std::memory_order_release);
17 18 19 20 21 22 23
    return false;
  }

  return true;
}

void swmr_spin_lock::reader_unlock() {
24
  readers_--;
25 26 27 28
}

void swmr_spin_lock::writer_lock() {
  // Tell the readers that we would like to write
29
  write_request_ = 1;
30

31
  // Wait for all of them to exit the critical section
32
  while (readers_ > 0)
33 34 35 36
    system_details::relax_cpu(); // Spin, not expensive as relaxed load
}

void swmr_spin_lock::writer_unlock() {
37
  write_request_ = 0;
38 39 40 41 42
}

}
}
}