Add data structure benchmarks
[c11concurrency-benchmarks.git] / cdschecker_modified_benchmarks / dekker-fences / dekker-fences.cc
diff --git a/cdschecker_modified_benchmarks/dekker-fences/dekker-fences.cc b/cdschecker_modified_benchmarks/dekker-fences/dekker-fences.cc
new file mode 100644 (file)
index 0000000..30a3633
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Dekker's critical section algorithm, implemented with fences.
+ *
+ * URL:
+ *   http://www.justsoftwaresolutions.co.uk/threading/
+ */
+
+
+#include "cds_threads.h"
+//#include "cds_atomic.h"
+#include <atomic>
+
+#include "librace.h"
+
+std::atomic<bool> flag0, flag1;
+std::atomic<int> turn;
+
+uint32_t var = 0;
+
+void p0()
+{
+//     std::this_thread::sleep_for(std::chrono::milliseconds(10));
+
+       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)
+                       {
+                               thrd_yield();
+                       }
+                       flag0.store(true,std::memory_order_relaxed);
+                       std::atomic_thread_fence(std::memory_order_seq_cst);
+               } else
+                       thrd_yield();
+       }
+       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()
+{
+//     std::this_thread::sleep_for(std::chrono::milliseconds(10));
+
+       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)
+                       {
+                               thrd_yield();
+                       }
+                       flag1.store(true,std::memory_order_relaxed);
+                       std::atomic_thread_fence(std::memory_order_seq_cst);
+               } else
+                       thrd_yield();
+       }
+       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)
+{
+       flag0 = false;
+       flag1 = false;
+       turn = 0;
+
+       std::thread a(p0);
+       std::thread b(p1);
+
+       a.join();
+       b.join();
+
+       return 0;
+}