Commit state of repository at time of OOPSLA 2015 submission.
[satcheck.git] / benchmarks / nidhugg / seqlock / seqlock.c.in
1 #include <stdio.h>
2 #include <pthread.h>
3 #include <atomic>
4
5 std::atomic<int> _seq;
6 std::atomic<int> _data;
7
8 void seqlock_init() {
9         atomic_store_explicit(&_seq, 0, std::memory_order_release);
10         atomic_store_explicit(&_data, 0, std::memory_order_release);
11 }
12
13 int seqlock_read() {
14         int old_seq = atomic_load(&_seq);
15         
16         int c0 = (old_seq % 2 == 1);
17         if (!c0) {
18                 int res = atomic_load(&_data);
19                 int seq = atomic_load(&_seq);
20     
21                 int c1;
22                 c1 = seq == old_seq;
23                 if (c1) { // relaxed
24                         return res;
25                 }
26         }
27         return -1;
28 }
29
30 int seqlock_write(int new_data) {
31         int old_seq = atomic_load(&_seq);
32         int c2 = (old_seq % 2 == 1);
33         if (!c2) {
34                 int new_seq = old_seq + 1;
35                 if (atomic_compare_exchange_strong(&_seq, &old_seq, new_seq)) {
36                         atomic_store_explicit(&_data, new_data, std::memory_order_release);
37                         atomic_fetch_add(&_seq, 1);
38                         return true;
39                 }
40         }
41         return false;
42 }
43
44 void * a(void *obj) {
45 problemsize             seqlock_write(3);
46  return NULL;
47 }
48
49 void * b(void *obj) {
50         int r1;
51 problemsize             r1=seqlock_read();
52  return NULL;
53 }
54
55 void * c(void *obj) {
56         int r1;
57 problemsize     r1=seqlock_read();
58  return NULL;
59 }
60
61 int main(int argc, char **argv) {
62         pthread_t t1, t2, t3;
63         seqlock_init();
64
65         pthread_create(&t1, 0,&a, NULL);
66         pthread_create(&t2, 0,&b, NULL);
67         pthread_create(&t3, 0,&c, NULL);
68
69         pthread_join(t1,0);
70         pthread_join(t2,0);
71         pthread_join(t3,0);
72         return 0;
73 }