--- /dev/null
+#ifndef _SEQLOCK_H
+#define _SEQLOCK_H
+
+#include <atomic>
+
+namespace cds_others {
+
+using std::atomic_int;
+using std::memory_order_release;
+using std::memory_order_acquire;
+using std::memory_order_relaxed;
+
+class SeqLock {
+private:
+ // Sequence for reader consistency check.
+ atomic_int seq_;
+ // It needs to be atomic to avoid data races
+ atomic_int data_;
+
+public:
+ SeqLock() {
+ atomic_init(&seq_, 0);
+ atomic_init(&data_, 0);
+ }
+
+ int read() {
+ while (true) {
+ int old_seq = seq_.load(memory_order_acquire); // acquire
+ if (old_seq % 2 == 1)
+ continue;
+
+ int res = data_.load(memory_order_acquire); // acquire
+ if (seq_.load(memory_order_relaxed) == old_seq) { // relaxed
+ return res;
+ }
+ }
+ }
+
+ void write(int new_data) {
+ while (true) {
+ // This might be a relaxed too
+ int old_seq = seq_.load(memory_order_acquire); // acquire
+ if (old_seq % 2 == 1)
+ continue; // Retry
+
+ // Should be relaxed!!!
+ if (seq_.compare_exchange_strong(old_seq, old_seq + 1,
+ memory_order_relaxed,
+ memory_order_relaxed)) // relaxed
+ break;
+ }
+
+ // Update the data
+ data_.store(new_data, memory_order_release); // release
+
+ seq_.fetch_add(1, memory_order_release); // release
+ }
+};
+
+} // namespace cds_others
+
+#endif