7 atomic_init(&_data1, 0);
8 atomic_init(&_data2, 0);
11 /** @DeclareState: int data1;
14 void seqlock::read(int *data1, int *data2) {
16 // XXX-injection-#1: Weaken the parameter "memory_order_acquire" to
17 // "memory_order_relaxed", run "make" to recompile, and then run:
18 // "./run.sh ./seqlock/testcase1 -m2 -y -u3 -tSPEC"
20 /********** Detected Correctness (testcase1) **********/
21 int old_seq = _seq.load(memory_order_acquire); // acquire
22 if (old_seq % 2 == 1) {
27 // Acquire ensures that the second _seq reads an update-to-date value
28 *data1 = _data1.load(memory_order_relaxed);
29 *data2 = _data2.load(memory_order_relaxed);
30 /** @OPClearDefine: true */
32 // XXX-injection-#2: Weaken the parameter "memory_order_acquire" to
33 // "memory_order_relaxed", run "make" to recompile, and then run:
34 // "./run.sh ./seqlock/testcase1 -m2 -y -u3 -tSPEC"
35 /********** Detected Correctness (testcase1) **********/
36 atomic_thread_fence(memory_order_acquire);
37 if (_seq.load(memory_order_relaxed) == old_seq) { // relaxed
45 void seqlock::write(int data1, int data2) {
47 // #1: either here or #2 must be acquire
48 // XXX-injection-#3: Weaken the parameter "memory_order_acquire" to
49 // "memory_order_relaxed", run "make" to recompile, and then run:
50 // "./run.sh ./seqlock/testcase2 -m2 -y -u3 -x1000 -tSPEC"
51 /********** Detected Correctness (testcase2 with -y -x1000) **********/
52 int old_seq = _seq.load(memory_order_acquire); // acquire
53 if (old_seq % 2 == 1) {
59 if (_seq.compare_exchange_strong(old_seq, old_seq + 1,
60 memory_order_relaxed, memory_order_relaxed)) {
66 // Update the data. It needs to be release since this version use
67 // relaxed CAS in write(). When the first load of _seq reads the realaxed
68 // CAS update, it does not form synchronization, thus requiring the data to
69 // be acq/rel. The data in practice can be pointers to objects.
71 // XXX-injection-#4: Weaken the parameter "memory_order_release" to
72 // "memory_order_relaxed", run "make" to recompile, and then run:
73 // "./run.sh ./seqlock/testcase1 -m2 -y -u3 -tSPEC"
74 /********** Detected Correctness (testcase1) **********/
75 atomic_thread_fence(memory_order_release);
76 _data1.store(data1, memory_order_relaxed);
77 _data2.store(data2, memory_order_relaxed);
78 /** @OPDefine: true */
80 // XXX-injection-#5: Weaken the parameter "memory_order_release" to
81 // "memory_order_relaxed", run "make" to recompile, and then run:
82 // "./run.sh ./seqlock/testcase1 -m2 -y -u3 -tSPEC"
83 /********** Detected Correctness (testcase1) **********/
84 _seq.fetch_add(1, memory_order_release); // release
89 /** @Transition: STATE(data1) = data1;
90 STATE(data2) = data2; */
91 void write(seqlock *lock, int data1, int data2) {
92 lock->write(data1, data2);
96 /** @JustifyingPrecondition: return STATE(data1) == *data1 && STATE(data2) == *data2; */
97 void read(seqlock *lock, int *data1, int *data2) {
98 lock->read(data1, data2);