4 #include "libinterface.h"
6 typedef struct seqlock {
7 // Sequence for reader consistency check
9 // It needs to be atomic to avoid data races
13 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
15 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
23 //int old_seq = _seq.load(memory_order_acquire); // acquire
24 MCID mold_seq = MC2_nextOpLoad(MCID_NODEP);
25 int old_seq = load_32(&_seq);
27 int cond0 = (old_seq % 2 == 1);
28 MCID mcond0 = MC2_function(1, 4, cond0, mold_seq);
32 br0 = MC2_branchUsesID(mcond0, 1, 2, true);
36 br0 = MC2_branchUsesID(mcond0, 0, 2, true);
38 MCID mres = MC2_nextOpLoad(MCID_NODEP);
39 res = load_32(&_data);
41 MCID mseq = MC2_nextOpLoad(MCID_NODEP);
42 int seq = load_32(&_seq); // _seq.load(memory_order_relaxed)
44 int cond1 = seq == old_seq;
45 MCID mcond1 = MC2_function(2, 4, cond1, mseq, mold_seq);
47 if (cond1) { // relaxed
48 br1 = MC2_branchUsesID(mcond1, 1, 2, true);
51 br1 = MC2_branchUsesID(mcond1, 0, 2, true);
63 void write(int new_data) {
66 // This might be a relaxed too
67 //int old_seq = _seq.load(memory_order_acquire); // acquire
68 MCID mold_seq = MC2_nextOpLoad(MCID_NODEP);
69 int old_seq = load_32(&_seq);
71 int cond0 = (old_seq % 2 == 1);
72 MCID mcond0 = MC2_function(1, 4, cond0, mold_seq);
75 //retry as the integer is odd
76 br0 = MC2_branchUsesID(mcond0, 1, 2, true);
80 br0 = MC2_branchUsesID(mcond0, 0, 2, true);
82 int new_seq=old_seq+1;
83 MCID mnew_seq=MC2_function(1, 4, new_seq, mold_seq);
84 MCID m_priorval=MC2_nextRMW(MCID_NODEP, mold_seq, mnew_seq);
85 int cas_value=rmw_32(CAS, &_seq, old_seq, new_seq);
86 int exit=cas_value==old_seq;
87 MCID m_exit=MC2_function(2, 4, exit, m_priorval, mold_seq);
90 MCID br2=MC2_branchUsesID(m_exit, 1, 2, true);
93 MCID br2=MC2_branchUsesID(m_exit, 0, 2, true);
97 //if cas fails, we have to retry as someone else succeeded
104 //_data.store(new_data, memory_order_release); // release
105 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
106 store_32(&_data, new_data);
108 // _seq.fetch_add(1, memory_order_release); // release
109 MC2_nextRMW(MCID_NODEP, MCID_NODEP, MCID_NODEP);
110 rmw_32(ADD, &_seq, /* dummy */0, 1);
118 static void a(void *obj) {
122 static void b(void *obj) {
126 static void c(void *obj) {
127 int r1 = lock->read();
130 int user_main(int argc, char **argv) {
132 lock = new seqlock_t();
134 thrd_create(&t1, (thrd_start_t)&a, NULL);
135 thrd_create(&t2, (thrd_start_t)&b, NULL);
136 thrd_create(&t3, (thrd_start_t)&c, NULL);