remove unused code
[c11tester.git] / cmodelint.cc
1 #include <stdio.h>
2 #include <string>
3
4 #include "model.h"
5 #include "execution.h"
6 #include "action.h"
7 #include "cmodelint.h"
8 #include "snapshot-interface.h"
9 #include "threads-model.h"
10 #include "datarace.h"
11
12 memory_order orders[6] = {
13         memory_order_relaxed, memory_order_consume, memory_order_acquire,
14         memory_order_release, memory_order_acq_rel, memory_order_seq_cst,
15 };
16
17 /* ---  helper functions --- */
18 uint64_t model_rmwrcas_action_helper(void *obj, int atomic_index, uint64_t oldval, int size, const char *position) {
19         createModelIfNotExist();
20         return model->switch_thread(new ModelAction(ATOMIC_RMWRCAS, position, orders[atomic_index], obj, oldval, size));
21 }
22
23 uint64_t model_rmwr_action_helper(void *obj, int atomic_index, const char *position) {
24         createModelIfNotExist();
25         return model->switch_thread(new ModelAction(ATOMIC_RMWR, position, orders[atomic_index], obj));
26 }
27
28 void model_rmw_action_helper(void *obj, uint64_t val, int atomic_index, const char * position) {
29         createModelIfNotExist();
30         model->switch_thread(new ModelAction(ATOMIC_RMW, position, orders[atomic_index], obj, val));
31 }
32
33 void model_rmwc_action_helper(void *obj, int atomic_index, const char *position) {
34         createModelIfNotExist();
35         model->switch_thread(new ModelAction(ATOMIC_RMWC, position, orders[atomic_index], obj));
36 }
37
38 // cds volatile loads
39 #define VOLATILELOAD(size) \
40         uint ## size ## _t cds_volatile_load ## size(void * obj, const char * position) { \
41                 createModelIfNotExist();                                                      \
42                 return (uint ## size ## _t)model->switch_thread(new ModelAction(ATOMIC_READ, position, memory_order_volatile_load, obj)); \
43         }
44
45 VOLATILELOAD(8)
46 VOLATILELOAD(16)
47 VOLATILELOAD(32)
48 VOLATILELOAD(64)
49
50 // cds volatile stores
51 #define VOLATILESTORE(size) \
52         void cds_volatile_store ## size (void * obj, uint ## size ## _t val, const char * position) { \
53                 createModelIfNotExist();                                                      \
54                 model->switch_thread(new ModelAction(ATOMIC_WRITE, position, memory_order_volatile_store, obj, (uint64_t) val)); \
55                 *((volatile uint ## size ## _t *)obj) = val;            \
56                 thread_id_t tid = thread_current_id();           \
57                 for(int i=0;i < size / 8;i++) {                         \
58                         atomraceCheckWrite(tid, (void *)(((char *)obj)+i));          \
59                 }                                                       \
60         }
61
62 VOLATILESTORE(8)
63 VOLATILESTORE(16)
64 VOLATILESTORE(32)
65 VOLATILESTORE(64)
66
67 // cds atomic inits
68 #define CDSATOMICINT(size)                                              \
69         void cds_atomic_init ## size (void * obj, uint ## size ## _t val, const char * position) { \
70                 createModelIfNotExist();                                                      \
71                 model->switch_thread(new ModelAction(ATOMIC_INIT, position, memory_order_relaxed, obj, (uint64_t) val)); \
72                 *((volatile uint ## size ## _t *)obj) = val;                                 \
73                 thread_id_t tid = thread_current_id();           \
74                 for(int i=0;i < size / 8;i++) {                       \
75                         atomraceCheckWrite(tid, (void *)(((char *)obj)+i));          \
76                 }                                                       \
77         }
78
79 CDSATOMICINT(8)
80 CDSATOMICINT(16)
81 CDSATOMICINT(32)
82 CDSATOMICINT(64)
83
84 // cds atomic loads
85 #define CDSATOMICLOAD(size)                                             \
86         uint ## size ## _t cds_atomic_load ## size(void * obj, int atomic_index, const char * position) { \
87                 createModelIfNotExist();                                                      \
88                 uint ## size ## _t val = (uint ## size ## _t)model->switch_thread( \
89                         new ModelAction(ATOMIC_READ, position, orders[atomic_index], obj)); \
90                 thread_id_t tid = thread_current_id();           \
91                 for(int i=0;i < size / 8;i++) {                         \
92                         atomraceCheckRead(tid, (void *)(((char *)obj)+i));    \
93                 }                                                       \
94                 return val; \
95         }
96
97 CDSATOMICLOAD(8)
98 CDSATOMICLOAD(16)
99 CDSATOMICLOAD(32)
100 CDSATOMICLOAD(64)
101
102 // cds atomic stores
103 #define CDSATOMICSTORE(size)                                            \
104         void cds_atomic_store ## size(void * obj, uint ## size ## _t val, int atomic_index, const char * position) { \
105                 createModelIfNotExist();                                                        \
106                 model->switch_thread(new ModelAction(ATOMIC_WRITE, position, orders[atomic_index], obj, (uint64_t) val)); \
107                 *((volatile uint ## size ## _t *)obj) = val;                     \
108                 thread_id_t tid = thread_current_id();           \
109                 for(int i=0;i < size / 8;i++) {                       \
110                         atomraceCheckWrite(tid, (void *)(((char *)obj)+i));          \
111                 }                                                       \
112         }
113
114 CDSATOMICSTORE(8)
115 CDSATOMICSTORE(16)
116 CDSATOMICSTORE(32)
117 CDSATOMICSTORE(64)
118
119
120 #define _ATOMIC_RMW_(__op__, size, addr, val, atomic_index, position)            \
121         ({                                                                      \
122                 uint ## size ## _t _old = model_rmwr_action_helper(addr, atomic_index, position);   \
123                 uint ## size ## _t _copy = _old;                                          \
124                 uint ## size ## _t _val = val;                                            \
125                 _copy __op__ _val;                                                    \
126                 model_rmw_action_helper(addr, (uint64_t) _copy, atomic_index, position);        \
127                 *((volatile uint ## size ## _t *)addr) = _copy;                  \
128                 thread_id_t tid = thread_current_id();           \
129                 for(int i=0;i < size / 8;i++) {                       \
130                         atomraceCheckRead(tid,  (void *)(((char *)addr)+i));  \
131                         recordWrite(tid, (void *)(((char *)addr)+i));         \
132                 }                                                       \
133                 return _old;                                            \
134         })
135
136 // cds atomic exchange
137 #define CDSATOMICEXCHANGE(size)                                         \
138         uint ## size ## _t cds_atomic_exchange ## size(void* addr, uint ## size ## _t val, int atomic_index, const char * position) { \
139                 _ATOMIC_RMW_( =, size, addr, val, atomic_index, position);          \
140         }
141
142 CDSATOMICEXCHANGE(8)
143 CDSATOMICEXCHANGE(16)
144 CDSATOMICEXCHANGE(32)
145 CDSATOMICEXCHANGE(64)
146
147 // cds atomic fetch add
148 #define CDSATOMICADD(size)                                              \
149         uint ## size ## _t cds_atomic_fetch_add ## size(void* addr, uint ## size ## _t val, int atomic_index, const char * position) { \
150                 _ATOMIC_RMW_( +=, size, addr, val, atomic_index, position);         \
151         }
152
153 CDSATOMICADD(8)
154 CDSATOMICADD(16)
155 CDSATOMICADD(32)
156 CDSATOMICADD(64)
157
158 // cds atomic fetch sub
159 #define CDSATOMICSUB(size)                                              \
160         uint ## size ## _t cds_atomic_fetch_sub ## size(void* addr, uint ## size ## _t val, int atomic_index, const char * position) { \
161                 _ATOMIC_RMW_( -=, size, addr, val, atomic_index, position);         \
162         }
163
164 CDSATOMICSUB(8)
165 CDSATOMICSUB(16)
166 CDSATOMICSUB(32)
167 CDSATOMICSUB(64)
168
169 // cds atomic fetch and
170 #define CDSATOMICAND(size)                                              \
171         uint ## size ## _t cds_atomic_fetch_and ## size(void* addr, uint ## size ## _t val, int atomic_index, const char * position) { \
172                 _ATOMIC_RMW_( &=, size, addr, val, atomic_index, position);         \
173         }
174
175 CDSATOMICAND(8)
176 CDSATOMICAND(16)
177 CDSATOMICAND(32)
178 CDSATOMICAND(64)
179
180 // cds atomic fetch or
181 #define CDSATOMICOR(size)                                               \
182         uint ## size ## _t cds_atomic_fetch_or ## size(void* addr, uint ## size ## _t val, int atomic_index, const char * position) { \
183                 _ATOMIC_RMW_( |=, size, addr, val, atomic_index, position);         \
184         }
185
186 CDSATOMICOR(8)
187 CDSATOMICOR(16)
188 CDSATOMICOR(32)
189 CDSATOMICOR(64)
190
191 // cds atomic fetch xor
192 #define CDSATOMICXOR(size)                                              \
193         uint ## size ## _t cds_atomic_fetch_xor ## size(void* addr, uint ## size ## _t val, int atomic_index, const char * position) { \
194                 _ATOMIC_RMW_( ^=, size, addr, val, atomic_index, position);         \
195         }
196
197 CDSATOMICXOR(8)
198 CDSATOMICXOR(16)
199 CDSATOMICXOR(32)
200 CDSATOMICXOR(64)
201
202 // cds atomic compare and exchange
203 // In order to accomodate the LLVM PASS, the return values are not true or false.
204
205 #define _ATOMIC_CMPSWP_WEAK_ _ATOMIC_CMPSWP_
206 #define _ATOMIC_CMPSWP_(size, addr, expected, desired, atomic_index, position)                            \
207         ({                                                                                              \
208                 uint ## size ## _t _desired = desired;                                                            \
209                 uint ## size ## _t _expected = expected;                                                          \
210                 uint ## size ## _t _old = model_rmwrcas_action_helper(addr, atomic_index, _expected, sizeof(_expected), position); \
211                 if (_old == _expected) {                                                                    \
212                         model_rmw_action_helper(addr, (uint64_t) _desired, atomic_index, position); \
213                         *((volatile uint ## size ## _t *)addr) = desired;                        \
214                         thread_id_t tid = thread_current_id();           \
215                         for(int i=0;i < size / 8;i++) {                       \
216                                 recordWrite(tid, (void *)(((char *)addr)+i));         \
217                         }                                                       \
218                         return _expected; }                                     \
219                 else {                                                                                        \
220                         model_rmwc_action_helper(addr, atomic_index, position); _expected = _old; return _old; }              \
221         })
222
223 // atomic_compare_exchange version 1: the CmpOperand (corresponds to expected)
224 // extracted from LLVM IR is an integer type.
225 #define CDSATOMICCASV1(size)                                            \
226         uint ## size ## _t cds_atomic_compare_exchange ## size ## _v1(void* addr, uint ## size ## _t expected, uint ## size ## _t desired, int atomic_index_succ, int atomic_index_fail, const char *position) { \
227                 _ATOMIC_CMPSWP_(size, addr, expected, desired, atomic_index_succ, position); \
228         }
229
230 CDSATOMICCASV1(8)
231 CDSATOMICCASV1(16)
232 CDSATOMICCASV1(32)
233 CDSATOMICCASV1(64)
234
235 // atomic_compare_exchange version 2
236 #define CDSATOMICCASV2(size)                                            \
237         bool cds_atomic_compare_exchange ## size ## _v2(void* addr, uint ## size ## _t* expected, uint ## size ## _t desired, int atomic_index_succ, int atomic_index_fail, const char *position) { \
238                 uint ## size ## _t ret = cds_atomic_compare_exchange ## size ## _v1(addr, *expected, desired, atomic_index_succ, atomic_index_fail, position); \
239                 if (ret == *expected) {return true;} else {return false;}               \
240         }
241
242 CDSATOMICCASV2(8)
243 CDSATOMICCASV2(16)
244 CDSATOMICCASV2(32)
245 CDSATOMICCASV2(64)
246
247 // cds atomic thread fence
248
249 void cds_atomic_thread_fence(int atomic_index, const char * position) {
250         model->switch_thread(
251                 new ModelAction(ATOMIC_FENCE, position, orders[atomic_index], FENCE_LOCATION)
252                 );
253 }
254
255 /*
256  #define _ATOMIC_CMPSWP_( __a__, __e__, __m__, __x__ )                         \
257         ({ volatile __typeof__((__a__)->__f__)* __p__ = & ((__a__)->__f__);   \
258                 __typeof__(__e__) __q__ = (__e__);                            \
259                 __typeof__(__m__) __v__ = (__m__);                            \
260                 bool __r__;                                                   \
261                 __typeof__((__a__)->__f__) __t__=(__typeof__((__a__)->__f__)) model_rmwr_action((void *)__p__, __x__); \
262                 if (__t__ == * __q__ ) {                                      \
263                         model_rmw_action((void *)__p__, __x__, (uint64_t) __v__); __r__ = true; } \
264                 else {  model_rmwc_action((void *)__p__, __x__); *__q__ = __t__;  __r__ = false;} \
265                 __r__; })
266
267  #define _ATOMIC_FENCE_( __x__ ) \
268         ({ model_fence_action(__x__);})
269  */
270
271 /*
272
273  #define _ATOMIC_MODIFY_( __a__, __o__, __m__, __x__ )                         \
274         ({ volatile __typeof__((__a__)->__f__)* __p__ = & ((__a__)->__f__);   \
275         __typeof__((__a__)->__f__) __old__=(__typeof__((__a__)->__f__)) model_rmwr_action((void *)__p__, __x__); \
276         __typeof__(__m__) __v__ = (__m__);                                    \
277         __typeof__((__a__)->__f__) __copy__= __old__;                         \
278         __copy__ __o__ __v__;                                                 \
279         model_rmw_action((void *)__p__, __x__, (uint64_t) __copy__);          \
280         __old__ = __old__;  Silence clang (-Wunused-value)                    \
281          })
282  */
283
284 void cds_func_entry(const char * funcName) {
285 }
286
287 void cds_func_exit(const char * funcName) {
288 }