--- /dev/null
+include ../benchmarks.mk
+
+TESTNAME = spsc-queue
+
+all: $(TESTNAME)
+
+$(TESTNAME): $(TESTNAME).cc queue.h
+ $(CXX) -o $@ $< $(CXXFLAGS) $(LDFLAGS)
+
+clean:
+ rm -f $(TESTNAME) *.o
--- /dev/null
+This is the example used in the scfence example section in the paper.
+We need to deal with the problem of data races.
--- /dev/null
+#include <unrelacy.h>
+#include <atomic>
+
+using namespace std;
+
+struct node {
+ node(int d): data(d) {
+ next.store(0, memory_order_relaxed);
+ }
+ atomic<node*> next;
+ int data;
+};
+
+class spsc_queue
+{
+ atomic<node*> head, tail;
+ public:
+ spsc_queue() {
+ head = tail = new node(0);
+ }
+
+ void enqueue(int val) {
+ node* n = new node(val);
+ node *h = head.load(memory_order_relaxed);
+ h->next.store(n, memory_order_release);
+ head.store(n, memory_order_relaxed);
+ }
+
+ bool dequeue(int *v) {
+ node* t = tail.load(memory_order_relaxed);
+ node* n = t->next.load(memory_order_acquire);
+ if (0 == n)
+ return false;
+ *v = n->data;
+ tail.store(n, memory_order_relaxed);
+ delete (t);
+ return true;
+ }
+};
--- /dev/null
+#include <threads.h>
+
+#include "queue.h"
+
+spsc_queue *q;
+atomic_int arr[2];
+
+void thread(unsigned thread_index)
+{
+ if (0 == thread_index)
+ {
+ arr[1].store(memory_order_relaxed);
+ q->enqueue(1);
+ }
+ else
+ {
+ int val = 0;
+ bool succ = q->dequeue(&val);
+ arr[val].load(memory_order_relaxed);
+ }
+}
+
+int user_main(int argc, char **argv)
+{
+ thrd_t A, B;
+
+ q = new spsc_queue();
+
+ thrd_create(&A, (thrd_start_t)&thread, (void *)0);
+ thrd_create(&B, (thrd_start_t)&thread, (void *)1);
+ thrd_join(A);
+ thrd_join(B);
+
+ delete q;
+
+ return 0;
+}