7 atomic_init(&_data1, 0);
8 atomic_init(&_data2, 0);
11 /** @DeclareState: int data1;
14 void seqlock::read(int *data1, int *data2) {
16 // XXX: This cannot be detected unless when we only have a single data
17 // varaible since that becomes a plain load/store. However, when we have
18 // multiple data pieces, we will detect the inconsitency of the data.
19 /********** Detected Correctness (testcase1) **********/
20 int old_seq = _seq.load(memory_order_acquire); // acquire
21 if (old_seq % 2 == 1) {
26 // Acquire ensures that the second _seq reads an update-to-date value
27 /********** Detected Correctness (testcase1) **********/
28 *data1 = _data1.load(memory_order_relaxed);
29 *data2 = _data2.load(memory_order_relaxed);
30 /** @OPClearDefine: true */
31 /********** Detected Correctness (testcase1) **********/
32 atomic_thread_fence(memory_order_acquire);
33 if (_seq.load(memory_order_relaxed) == old_seq) { // relaxed
41 void seqlock::write(int data1, int data2) {
43 // #1: either here or #2 must be acquire
44 /********** Detected Correctness (testcase2 with -y -x1000) **********/
45 int old_seq = _seq.load(memory_order_acquire); // acquire
46 if (old_seq % 2 == 1) {
52 if (_seq.compare_exchange_strong(old_seq, old_seq + 1,
53 memory_order_relaxed, memory_order_relaxed)) {
59 // XXX: Update the data. It needs to be release since this version use
60 // relaxed CAS in write(). When the first load of _seq reads the realaxed
61 // CAS update, it does not form synchronization, thus requiring the data to
62 // be acq/rel. The data in practice can be pointers to objects.
63 /********** Detected Correctness (testcase1) **********/
64 atomic_thread_fence(memory_order_release);
65 _data1.store(data1, memory_order_relaxed);
66 _data2.store(data2, memory_order_relaxed);
67 /** @OPDefine: true */
69 /********** Detected Admissibility (testcase1) **********/
70 _seq.fetch_add(1, memory_order_release); // release
75 /** @Transition: STATE(data1) = data1;
76 STATE(data2) = data2; */
77 void write(seqlock *lock, int data1, int data2) {
78 lock->write(data1, data2);
82 /** @JustifyingPrecondition: return STATE(data1) == *data1 && STATE(data2) == *data2; */
83 void read(seqlock *lock, int *data1, int *data2) {
84 lock->read(data1, data2);