minor fix
[cdsspec-compiler.git] / benchmark / read-copy-update / rcu.cc
1 #include <atomic>
2 #include <threads.h>
3 #include <stdatomic.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6
7 #include "librace.h"
8
9 /**
10         This is an example about how to specify the correctness of the
11         read-copy-update synchronization mechanism.
12 */
13
14 typedef struct Data {
15         int data1;
16         int data2;
17         int data3;
18 } Data;
19
20 atomic<Data*> data;
21         
22 /**
23         @Begin
24         @Global_define:
25                 @DeclareVar:
26                         Data *_cur_data;
27                 @InitVar:
28                         _cur_data = NULL;
29                 
30                 @DefineFunc:
31                 bool equals(Data *ptr1, Data *ptr2) {
32                         if (ptr1->data1 == ptr2->data1
33                                 && ptr1->data2 == ptr2->data2
34                                 && ptr1->data3 == ptr2->data3) {
35                                 return true;
36                         } else {
37                                 return false;
38                         }
39                 }
40
41         @Happens_before:
42                 Write -> Read
43                 Write -> Write
44         @End
45 */
46
47 /**
48         @Begin
49         @Interface: Read
50         @Commit_point_set: Read_Success_Point
51         @Action:
52                 Data *_Old_Data = _cur_data;
53         @Post_check:
54                 equals(__RET__, _Old_Data)
55         @End
56 */
57 Data* read() {
58         Data *res = data.load(memory_order_acquire);
59         /**
60                 @Begin
61                 @Commit_point_define_check: true
62                 @Label: Read_Success_Point
63                 @End
64         */
65         return res;
66 }
67
68 /**
69         @Begin
70         @Interface: Write
71         @Commit_point_set: Write_Success_Point
72         @Action:
73                 _cur_data = new_data;
74         @End
75 */
76 void write(Data *new_data) {
77         while (true) {
78                 Data *prev = data.load(memory_order_relaxed);
79                 bool succ = data.compare_exchange_strong(prev, new_data,
80                         memory_order_release, memory_order_relaxed); 
81                 /**
82                         @Begin
83                         @Commit_point_define_check: succ == true
84                         @Label: Write_Success_Point
85                         @End
86                 */
87                 if (succ) {
88                         break;
89                 }
90         }
91 }
92
93 void threadA(void *arg) {
94         Data *dataA = (Data*) malloc(sizeof(Data));
95         dataA->data1 = 3;
96         dataA->data2 = 2;
97         dataA->data3 = 1;
98         write(dataA);
99 }
100
101 void threadB(void *arg) {
102         Data *dataB = read();
103         printf("ThreadB data1: %d\n", dataB->data1);
104         printf("ThreadB data2: %d\n", dataB->data2);
105         printf("ThreadB data3: %d\n", dataB->data3);
106 }
107
108 void threadC(void *arg) {
109         Data *dataC = read();
110         printf("ThreadC data1: %d\n", dataC->data1);
111         printf("ThreadC data2: %d\n", dataC->data2);
112         printf("ThreadC data3: %d\n", dataC->data3);
113 }
114
115 void threadD(void *arg) {
116         Data *dataD = (Data*) malloc(sizeof(Data));
117         dataD->data1 = -3;
118         dataD->data2 = -2;
119         dataD->data3 = -1;
120         write(dataD);
121 }
122
123 int user_main(int argc, char **argv) {
124         /**
125                 @Begin
126                 @Entry_point
127                 @End
128         */
129         
130         thrd_t t1, t2, t3, t4;
131         data.store(NULL, memory_order_relaxed);
132         Data *data_init = (Data*) malloc(sizeof(Data));
133         data_init->data1 = 1;
134         data_init->data2 = 2;
135         data_init->data3 = 3;
136         write(data_init);
137
138         thrd_create(&t1, threadA, NULL);
139         thrd_create(&t2, threadB, NULL);
140         //thrd_create(&t3, threadC, NULL);
141         thrd_create(&t4, threadD, NULL);
142
143         thrd_join(t1);
144         thrd_join(t2);
145         //thrd_join(t3);
146         thrd_join(t4);
147
148         return 0;
149 }