X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=dekker-fences%2Fdekker-fences.cc;fp=dekker-fences%2Fdekker-fences.cc;h=81f609846cd2a8777a707ba12eedec38a9534068;hb=3a122c7c1a08bff6cbff5b81f357c5c6efaad84d;hp=0000000000000000000000000000000000000000;hpb=f0420375f1cec3bb95282dcac083a0ae9ed098b6;p=model-checker-benchmarks.git diff --git a/dekker-fences/dekker-fences.cc b/dekker-fences/dekker-fences.cc new file mode 100644 index 0000000..81f6098 --- /dev/null +++ b/dekker-fences/dekker-fences.cc @@ -0,0 +1,87 @@ +/* + * Dekker's critical section algorithm, implemented with fences. + * + * URL: + * http://www.justsoftwaresolutions.co.uk/threading/ + */ + +#include +#include + +#include "librace.h" + +std::atomic flag0, flag1; +std::atomic turn; + +uint32_t var = 0; + +void p0(void *arg) +{ + flag0.store(true,std::memory_order_relaxed); + std::atomic_thread_fence(std::memory_order_seq_cst); + + while (flag1.load(std::memory_order_relaxed)) + { + if (turn.load(std::memory_order_relaxed) != 0) + { + flag0.store(false,std::memory_order_relaxed); + while (turn.load(std::memory_order_relaxed) != 0) + { + } + flag0.store(true,std::memory_order_relaxed); + std::atomic_thread_fence(std::memory_order_seq_cst); + } + } + std::atomic_thread_fence(std::memory_order_acquire); + + // critical section + store_32(&var, 1); + + turn.store(1,std::memory_order_relaxed); + std::atomic_thread_fence(std::memory_order_release); + flag0.store(false,std::memory_order_relaxed); +} + +void p1(void *arg) +{ + flag1.store(true,std::memory_order_relaxed); + std::atomic_thread_fence(std::memory_order_seq_cst); + + while (flag0.load(std::memory_order_relaxed)) + { + if (turn.load(std::memory_order_relaxed) != 1) + { + flag1.store(false,std::memory_order_relaxed); + while (turn.load(std::memory_order_relaxed) != 1) + { + } + flag1.store(true,std::memory_order_relaxed); + std::atomic_thread_fence(std::memory_order_seq_cst); + } + } + std::atomic_thread_fence(std::memory_order_acquire); + + // critical section + store_32(&var, 2); + + turn.store(0,std::memory_order_relaxed); + std::atomic_thread_fence(std::memory_order_release); + flag1.store(false,std::memory_order_relaxed); +} + +int user_main(int argc, char **argv) +{ + thrd_t a, b; + + flag0 = false; + flag1 = false; + turn = 0; + + thrd_create(&a, p0, NULL); + thrd_create(&b, p1, NULL); + + thrd_join(a); + thrd_join(b); + + return 0; +}