+++ /dev/null
-#ifndef _RWLOCK_H
-#define _RWLOCK_H
-
-#include "backoff.h"
-#include <atomic>
-#include <cds/algo/backoff_strategy.h>
-#include <thread>
-
-namespace cds_others {
-
-#define RW_LOCK_BIAS 0x00100000
-#define WRITE_LOCK_CMP RW_LOCK_BIAS
-
-using std::memory_order_acquire;
-using std::memory_order_release;
-using std::memory_order_relaxed;
-using std::atomic_int;
-
-class RWLock {
-public:
- RWLock() {
- lock.store(RW_LOCK_BIAS);
- }
-
- int read_can_lock() {
- return atomic_load_explicit(&lock, memory_order_relaxed) > 0;
- }
-
- int write_can_lock() {
- return atomic_load_explicit(&lock, memory_order_relaxed) == RW_LOCK_BIAS;
- }
-
- void read_lock() {
- ExpBackoff backoff;
- int priorvalue = atomic_fetch_sub_explicit(&lock, 1, memory_order_acquire);
- while (priorvalue <= 0) {
- atomic_fetch_add_explicit(&lock, 1, memory_order_relaxed);
- while (atomic_load_explicit(&lock, memory_order_relaxed) <= 0) {
- backoff();
- }
- priorvalue = atomic_fetch_sub_explicit(&lock, 1, memory_order_acquire);
- }
- }
-
- void write_lock() {
- int priorvalue =
- atomic_fetch_sub_explicit(&lock, RW_LOCK_BIAS, memory_order_acquire);
- ExpBackoff backoff;
- while (priorvalue != RW_LOCK_BIAS) {
- atomic_fetch_add_explicit(&lock, RW_LOCK_BIAS, memory_order_relaxed);
- while (atomic_load_explicit(&lock, memory_order_relaxed) !=
- RW_LOCK_BIAS) {
- backoff();
- }
- priorvalue =
- atomic_fetch_sub_explicit(&lock, RW_LOCK_BIAS, memory_order_acquire);
- }
- }
-
- int read_trylock() {
- int priorvalue = atomic_fetch_sub_explicit(&lock, 1, memory_order_acquire);
- if (priorvalue > 0)
- return 1;
-
- atomic_fetch_add_explicit(&lock, 1, memory_order_relaxed);
- return 0;
- }
-
- int write_trylock() {
- int priorvalue =
- atomic_fetch_sub_explicit(&lock, RW_LOCK_BIAS, memory_order_acquire);
- if (priorvalue == RW_LOCK_BIAS)
- return 1;
-
- atomic_fetch_add_explicit(&lock, RW_LOCK_BIAS, memory_order_relaxed);
- return 0;
- }
-
- void read_unlock() {
- atomic_fetch_add_explicit(&lock, 1, memory_order_release);
- }
-
- void write_unlock() {
- atomic_fetch_add_explicit(&lock, RW_LOCK_BIAS, memory_order_release);
- }
-
-private:
- atomic_int lock;
-};
-
-} // namespace cds_others
-
-#endif