From: Peizhao Ou Date: Thu, 12 Feb 2015 06:59:43 +0000 (-0800) Subject: changes X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=280528092c1e033b6283f6c3ec30260c7c169cce;p=model-checker-benchmarks.git changes --- diff --git a/seqlock/Makefile b/seqlock/Makefile index 98375f9..16a0203 100644 --- a/seqlock/Makefile +++ b/seqlock/Makefile @@ -1,9 +1,14 @@ include ../benchmarks.mk -all: seqlock +WILDCARD_TESTS = testcase1 -seqlock: seqlock.c +all: seqlock $(WILDCARD_TESTS) + +seqlock: seqlock.c seqlock.h $(CXX) -o $@ $< $(CXXFLAGS) $(LDFLAGS) +$(WILDCARD_TESTS): % : %.c seqlock-wildcard.h + $(CXX) -o $@ $< $(CXXFLAGS) $(LDFLAGS) + clean: - rm -f seqlock + rm -f seqlock $(WILDCARD_TESTS) diff --git a/seqlock/seqlock-wildcard.h b/seqlock/seqlock-wildcard.h new file mode 100644 index 0000000..85686ea --- /dev/null +++ b/seqlock/seqlock-wildcard.h @@ -0,0 +1,48 @@ +#include +#include + +#include "wildcard.h" + +typedef struct seqlock { + // Sequence for reader consistency check + atomic_int _seq; + // It needs to be atomic to avoid data races + atomic_int _data; + + seqlock() { + atomic_init(&_seq, 0); + atomic_init(&_data, 0); + } + + int read() { + while (true) { + int old_seq = _seq.load(wildcard(1)); // acquire + if (old_seq % 2 == 1) continue; + + int res = _data.load(wildcard(2)); // acquire + if (_seq.load(wildcard(3)) == old_seq) { // relaxed + return res; + } + } + } + + void write(int new_data) { + while (true) { + // This might be a relaxed too + 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 + break; + } + + // Update the data + _data.store(new_data, wildcard(7)); // release + + _seq.fetch_add(1, wildcard(8)); // release + } + +} seqlock_t; diff --git a/seqlock/seqlock.c b/seqlock/seqlock.c index 3762374..d2e33b8 100644 --- a/seqlock/seqlock.c +++ b/seqlock/seqlock.c @@ -1,50 +1,7 @@ #include #include -typedef struct seqlock { - // Sequence for reader consistency check - atomic_int _seq; - // It needs to be atomic to avoid data races - atomic_int _data; - - seqlock() { - atomic_init(&_seq, 0); - atomic_init(&_data, 0); - } - - int read() { - while (true) { - int old_seq = _seq.load(memory_order_acquire); // acquire - if (old_seq % 2 == 1) continue; - - int res = _data.load(memory_order_acquire); // acquire - if (_seq.load(memory_order_relaxed) == old_seq) { // relaxed - return res; - } - } - } - - void write(int new_data) { - while (true) { - // This might be a relaxed too - int old_seq = _seq.load(memory_order_acquire); // acquire - if (old_seq % 2 == 1) - continue; // Retry - - // Should be relaxed!!! - if (_seq.compare_exchange_strong(old_seq, old_seq + 1, - memory_order_relaxed, memory_order_relaxed)) // relaxed - break; - } - - // Update the data - _data.store(new_data, memory_order_release); // release - - _seq.fetch_add(1, memory_order_release); // release - } - -} seqlock_t; - +#include "seqlock.h" seqlock_t *lock; diff --git a/seqlock/seqlock.h b/seqlock/seqlock.h new file mode 100644 index 0000000..f263bec --- /dev/null +++ b/seqlock/seqlock.h @@ -0,0 +1,46 @@ +#include +#include + +typedef struct seqlock { + // Sequence for reader consistency check + atomic_int _seq; + // It needs to be atomic to avoid data races + atomic_int _data; + + seqlock() { + atomic_init(&_seq, 0); + atomic_init(&_data, 0); + } + + int read() { + while (true) { + int old_seq = _seq.load(memory_order_acquire); // acquire + if (old_seq % 2 == 1) continue; + + int res = _data.load(memory_order_acquire); // acquire + if (_seq.load(memory_order_relaxed) == old_seq) { // relaxed + return res; + } + } + } + + void write(int new_data) { + while (true) { + // This might be a relaxed too + int old_seq = _seq.load(memory_order_acquire); // acquire + if (old_seq % 2 == 1) + continue; // Retry + + // Should be relaxed!!! + if (_seq.compare_exchange_strong(old_seq, old_seq + 1, + memory_order_relaxed, memory_order_relaxed)) // relaxed + break; + } + + // Update the data + _data.store(new_data, memory_order_release); // release + + _seq.fetch_add(1, memory_order_release); // release + } + +} seqlock_t; diff --git a/seqlock/testcase1.c b/seqlock/testcase1.c new file mode 100644 index 0000000..6417db3 --- /dev/null +++ b/seqlock/testcase1.c @@ -0,0 +1,32 @@ +#include +#include + +#include "seqlock-wildcard.h" + +seqlock_t *lock; + +static void a(void *obj) { + lock->write(3); +} + +static void b(void *obj) { + lock->write(2); +} + +static void c(void *obj) { + int r1 = lock->read(); +} + +int user_main(int argc, char **argv) { + thrd_t t1, t2, t3, t4; + 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_join(t1); + thrd_join(t2); + thrd_join(t3); + return 0; +}