4 typedef struct seqlock {
5 // Sequence for reader consistency check
7 // It needs to be atomic to avoid data races
11 atomic_init(&_seq, 0);
12 atomic_init(&_data, 0);
17 int old_seq = _seq.load(memory_order_acquire); // acquire
18 if (old_seq % 2 == 1) continue;
20 int res = _data.load(memory_order_acquire); // acquire
21 if (_seq.load(memory_order_relaxed) == old_seq) { // relaxed
27 void write(int new_data) {
29 // This might be a relaxed too
30 int old_seq = _seq.load(memory_order_acquire); // acquire
34 // Should be relaxed!!!
35 if (_seq.compare_exchange_strong(old_seq, old_seq + 1,
36 memory_order_relaxed, memory_order_relaxed)) // relaxed
41 _data.store(new_data, memory_order_release); // release
43 _seq.fetch_add(1, memory_order_release); // release
51 static void a(void *obj) {
55 static void b(void *obj) {
59 static void c(void *obj) {
60 int r1 = lock->read();
63 int user_main(int argc, char **argv) {
64 thrd_t t1, t2, t3, t4;
65 lock = new seqlock_t();
67 thrd_create(&t1, (thrd_start_t)&a, NULL);
68 thrd_create(&t2, (thrd_start_t)&b, NULL);
69 thrd_create(&t3, (thrd_start_t)&c, NULL);