8 typedef struct seqlock {
9 // Sequence for reader consistency check
11 // It needs to be atomic to avoid data races
21 void read(int * d1, int *d2) {
23 int old_seq = _seq.load(memory_order_acquire);
24 if (old_seq % 2 == 1) continue;
26 *d1 = _data1.load(memory_order_acquire);
27 *d2 = _data2.load(memory_order_acquire);
28 if (_seq.load(memory_order_relaxed) == old_seq) {
34 void write(int new_data, int new_data2) {
36 int old_seq = _seq.load(memory_order_relaxed); // Injected bug: should be acquire
40 if (_seq.compare_exchange_strong(old_seq, old_seq + 1,
41 memory_order_relaxed, memory_order_relaxed))
46 _data1.store(new_data, memory_order_release);
47 _data2.store(new_data, memory_order_release);
49 _seq.fetch_add(1, memory_order_release);
74 int main(int argc, char **argv) {
75 lock = new seqlock_t();
78 pthread_create(&t1, NULL, &a, NULL);
79 pthread_create(&t2, NULL, &b, NULL);
80 pthread_create(&t3, NULL, &c, NULL);
82 pthread_join(t1, NULL);
83 pthread_join(t2, NULL);
84 pthread_join(t3, NULL);