add seqlock
authorPeizhao Ou <peizhaoo@uci.edu>
Fri, 13 Feb 2015 08:03:10 +0000 (00:03 -0800)
committerPeizhao Ou <peizhaoo@uci.edu>
Fri, 13 Feb 2015 08:03:10 +0000 (00:03 -0800)
seqlock/note.txt [new file with mode: 0644]
seqlock/seqlock-wildcard.h
seqlock/seqlock.h
seqlock/testcase1.c

diff --git a/seqlock/note.txt b/seqlock/note.txt
new file mode 100644 (file)
index 0000000..6f27983
--- /dev/null
@@ -0,0 +1,6 @@
+Inference results for this benchmark are consistent with the manual analysis.
+In the write() function, either the load of _seq at the very beginning or the CAS
+of the _seq when it succeeds must be acquire such that it establishes
+synchronization between two contiguous write(). If not, the two _data.store
+operations are not ordered by hb, and the next read() can read either, thus
+allowing reading the wrong (old) value.
index 62b7583954bd446a4c224030117712321d5ff369..c7d0634e3b5a763fd234f5963f29beba7500f914 100644 (file)
@@ -27,14 +27,14 @@ typedef struct seqlock {
        }
        
        void write(int new_data) {
-               int old_seq = _seq.load(wildcard(4)); // acquire
                while (true) {
+                       int old_seq = _seq.load(wildcard(4)); // acquire
                        if (old_seq % 2 == 1)
                                continue; // Retry
 
                        // Should be relaxed!!! 
                        if (_seq.compare_exchange_strong(old_seq, old_seq + 1,
-                               wildcard(5), wildcard(6))) // relaxed 
+                               wildcard(5), wildcard(6))) // relaxed  
                                break;
                }
 
index c5a965cb8243bbb191ebe0620a72bdc50c0e4105..73e471f350618e6310e9eb8cea8e942a0802c0ea 100644 (file)
@@ -1,5 +1,6 @@
 #include <stdatomic.h>
 #include <threads.h>
+#include "common.h"
 
 typedef struct seqlock {
        // Sequence for reader consistency check
@@ -25,14 +26,16 @@ typedef struct seqlock {
        }
        
        void write(int new_data) {
-               int old_seq = _seq.load(memory_order_acquire); // acquire
                while (true) {
+                       // #1: either here or #2 must be acquire
+                       int old_seq = _seq.load(memory_order_acquire); // acquire
                        // This might be a relaxed too
                        if (old_seq % 2 == 1)
                                continue; // Retry
 
+                       // #2
                        if (_seq.compare_exchange_strong(old_seq, old_seq + 1,
-                               memory_order_acq_rel, memory_order_acquire)) 
+                               memory_order_relaxed, memory_order_relaxed)) 
                                break;
                }
 
index 8441972702762d0ab33aef89f5ca9c435331fae8..0c9e49cf1c3662d9158775117264ce5273d33ca2 100644 (file)
@@ -11,10 +11,10 @@ static void a(void *obj) {
 
 static void b(void *obj) {
        lock->write(2);
+       int r1 = lock->read();
 }
 
 static void c(void *obj) {
-       lock->write(2);
        int r1 = lock->read();
 }
 
@@ -23,11 +23,11 @@ int user_main(int argc, char **argv) {
        lock = new seqlock_t();
 
        thrd_create(&t1, (thrd_start_t)&a, NULL);
-       //thrd_create(&t2, (thrd_start_t)&b, NULL);
-       thrd_create(&t3, (thrd_start_t)&c, NULL);
+       thrd_create(&t2, (thrd_start_t)&b, NULL);
+       //thrd_create(&t3, (thrd_start_t)&c, NULL);
 
        thrd_join(t1);
-       //thrd_join(t2);
-       thrd_join(t3);
+       thrd_join(t2);
+       //thrd_join(t3);
        return 0;
 }