5 #include "libinterface.h"
7 typedef struct seqlock {
8 // Sequence for reader consistency check
10 // It needs to be atomic to avoid data races
14 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
16 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
24 //int old_seq = _seq.load(memory_order_acquire); // acquire
25 MCID mold_seq = MC2_nextOpLoad(MCID_NODEP);
26 int old_seq = load_32(&_seq);
28 int cond0 = (old_seq % 2 == 1);
29 MCID mcond0 = MC2_function(1, 4, cond0, mold_seq);
33 br0 = MC2_branchUsesID(mcond0, 1, 2, true);
37 br0 = MC2_branchUsesID(mcond0, 0, 2, true);
39 MCID mres = MC2_nextOpLoad(MCID_NODEP);
40 res = load_32(&_data);
42 MCID mseq = MC2_nextOpLoad(MCID_NODEP);
43 int seq = load_32(&_seq); // _seq.load(memory_order_relaxed)
45 int cond1 = seq == old_seq;
46 MCID mcond1 = MC2_function(2, 4, cond1, mseq, mold_seq);
48 if (cond1) { // relaxed
49 br1 = MC2_branchUsesID(mcond1, 1, 2, true);
52 br1 = MC2_branchUsesID(mcond1, 0, 2, true);
64 void write(int new_data) {
67 // This might be a relaxed too
68 //int old_seq = _seq.load(memory_order_acquire); // acquire
69 MCID mold_seq = MC2_nextOpLoad(MCID_NODEP);
70 int old_seq = load_32(&_seq);
72 int cond0 = (old_seq % 2 == 1);
73 MCID mcond0 = MC2_function(1, 4, cond0, mold_seq);
76 //retry as the integer is odd
77 br0 = MC2_branchUsesID(mcond0, 1, 2, true);
81 br0 = MC2_branchUsesID(mcond0, 0, 2, true);
83 int new_seq=old_seq+1;
84 MCID mnew_seq=MC2_function(1, 4, new_seq, mold_seq);
85 MCID m_priorval=MC2_nextRMW(MCID_NODEP, mold_seq, mnew_seq);
86 int cas_value=rmw_32(CAS, &_seq, old_seq, new_seq);
87 int exit=cas_value==old_seq;
88 MCID m_exit=MC2_function(2, 4, exit, m_priorval, mold_seq);
91 MCID br2=MC2_branchUsesID(m_exit, 1, 2, true);
94 MCID br2=MC2_branchUsesID(m_exit, 0, 2, true);
98 //if cas fails, we have to retry as someone else succeeded
105 //_data.store(new_data, memory_order_release); // release
106 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
107 store_32(&_data, new_data);
109 // _seq.fetch_add(1, memory_order_release); // release
110 MC2_nextRMW(MCID_NODEP, MCID_NODEP, MCID_NODEP);
111 rmw_32(ADD, &_seq, /* dummy */0, 1);
119 static void a(void *obj) {
123 static void b(void *obj) {
127 static void c(void *obj) {
128 int r1 = lock->read();
131 int user_main(int argc, char **argv) {
133 lock = new seqlock_t();
135 thrd_create(&t1, (thrd_start_t)&a, NULL);
136 thrd_create(&t2, (thrd_start_t)&b, NULL);
137 thrd_create(&t3, (thrd_start_t)&c, NULL);