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