Commit state of repository at time of OOPSLA 2015 submission.
[satcheck.git] / clang / test / seqlock_raw_unannotated.c
1 #include <stdio.h>
2 #include <threads.h>
3 #include <stdatomic.h>
4
5 #include <stdatomic.h>
6 #include "threads.h"
7 #include "libinterface.h"
8
9 /*atomic_*/ int _seq;
10 /*atomic_*/ int _data;
11
12 void seqlock_init() {
13         store_32(&_seq, 0);
14         store_32(&_data, 0);
15 }
16
17 int seqlock_read() {
18         while (true) {
19                 int old_seq = load_32(&_seq);
20
21                 if (old_seq % 2 == 1) {
22                 } else {
23                         int res = load_32(&_data);
24                         int seq = load_32(&_seq);
25                         
26                         if (seq == old_seq) { // relaxed
27                                 return res;
28                         }
29                 }
30         }
31 }
32         
33 void seqlock_write(int new_data) {
34         while (true) {
35                 int old_seq = load_32(&_seq);
36                 if (old_seq % 2 == 1) {
37                 } else {
38                         int new_seq = old_seq + 1;
39                         int cas_value = rmw_32(CAS, &_seq, old_seq, new_seq);
40                         if (old_seq == cas_value) {
41                                 break;
42                         }
43                 }
44         }
45         store_32(&_data, new_data);
46
47         rmw_32(ADD, &_seq, /*dummy */0, 1);
48 }
49
50 static void a(void *obj) {
51         seqlock_write(3);
52 }
53
54 static void b(void *obj) {
55         seqlock_write(2);
56 }
57
58 static void c(void *obj) {
59         int r1 = seqlock_read();
60 }
61
62 int user_main(int argc, char **argv) {
63         thrd_t t1, t2, t3;
64         seqlock_init();
65
66         thrd_create(&t1, (thrd_start_t)&a, NULL);
67         thrd_create(&t2, (thrd_start_t)&b, NULL);
68         thrd_create(&t3, (thrd_start_t)&c, NULL);
69
70         thrd_join(t1);
71         thrd_join(t2);
72         thrd_join(t3);
73         return 0;
74 }