Last active
September 30, 2017 23:33
-
-
Save jac18281828/71899c186f93ca032cf258ce42395e5f to your computer and use it in GitHub Desktop.
Hans-J. Boehm sequence lock in c++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <stdatomic.h> | |
#include <atomic> | |
#include <sys/types.h> | |
#define PAUSE asm volatile("pause\n": : :"memory"); | |
class seq_lock { | |
private: | |
std::atomic<size_t> sequence; | |
public: | |
seq_lock() { | |
sequence.store(2L, std::memory_order_relaxed); | |
} | |
size_t read_lock() { | |
return sequence.load(std::memory_order_acquire); | |
} | |
bool read_lock_held(size_t lock_token) { | |
std::atomic_thread_fence(std::memory_order_acquire); | |
size_t const seq = sequence.load(std::memory_order_relaxed); | |
return seq == lock_token && (lock_token & 1L) == 0L; | |
} | |
size_t write_lock() { | |
size_t seq0 = sequence.load(std::memory_order_acquire); | |
// lock acquire | |
for(;;) { | |
if((seq0 & 1) == 0 && | |
sequence.compare_exchange_weak(seq0, seq0 + 1)) { | |
return seq0; | |
} | |
PAUSE | |
} | |
} | |
size_t try_write_lock() { | |
size_t seq0 = sequence.load(std::memory_order_acquire); | |
// lock acquire | |
if((seq0 & 1) == 0 && | |
sequence.compare_exchange_weak(seq0, seq0 + 1)) { | |
return seq0; | |
} | |
return 0; | |
} | |
void unlock(size_t lock_token) { | |
sequence.store(lock_token + 2, std::memory_order_release); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment