From: Peizhao Ou Date: Wed, 4 Mar 2015 01:31:58 +0000 (-0800) Subject: spsc example X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b9a23d48995f9667fc94a85d1309e02811aa153f;p=model-checker-benchmarks.git spsc example --- diff --git a/spsc-example/Makefile b/spsc-example/Makefile new file mode 100644 index 0000000..defccdd --- /dev/null +++ b/spsc-example/Makefile @@ -0,0 +1,11 @@ +include ../benchmarks.mk + +TESTNAME = spsc-queue + +all: $(TESTNAME) + +$(TESTNAME): $(TESTNAME).cc queue.h + $(CXX) -o $@ $< $(CXXFLAGS) $(LDFLAGS) + +clean: + rm -f $(TESTNAME) *.o diff --git a/spsc-example/note.txt b/spsc-example/note.txt new file mode 100644 index 0000000..c12ab95 --- /dev/null +++ b/spsc-example/note.txt @@ -0,0 +1,2 @@ +This is the example used in the scfence example section in the paper. +We need to deal with the problem of data races. diff --git a/spsc-example/queue.h b/spsc-example/queue.h new file mode 100644 index 0000000..76430e7 --- /dev/null +++ b/spsc-example/queue.h @@ -0,0 +1,39 @@ +#include +#include + +using namespace std; + +struct node { + node(int d): data(d) { + next.store(0, memory_order_relaxed); + } + atomic next; + int data; +}; + +class spsc_queue +{ + atomic 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; + } +}; diff --git a/spsc-example/spsc-queue.cc b/spsc-example/spsc-queue.cc new file mode 100644 index 0000000..cfb34ec --- /dev/null +++ b/spsc-example/spsc-queue.cc @@ -0,0 +1,37 @@ +#include + +#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; +}