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