bench.sh: don't run tests twice
[model-checker-benchmarks.git] / include / unrelacy.h
1 #ifndef __UNRELACY_H__
2 #define __UNRELACY_H__
3
4 #include <stdatomic.h>
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <mutex>
8 #include <condition_variable>
9
10 #include <model-assert.h>
11 #include <librace.h>
12
13 #define $
14
15 #define ASSERT(expr) MODEL_ASSERT(expr)
16 #define RL_ASSERT(expr) MODEL_ASSERT(expr)
17
18 #define RL_NEW new
19 #define RL_DELETE(expr) delete expr
20
21 #define mo_seqcst memory_order_relaxed
22 #define mo_release memory_order_release
23 #define mo_acquire memory_order_acquire
24 #define mo_acq_rel memory_order_acq_rel
25 #define mo_relaxed memory_order_relaxed
26
27 namespace rl {
28
29         /* This 'useless' struct is declared just so we can use partial template
30          * specialization in our store and load functions. */
31         template <typename T, size_t n>
32         struct useless {
33                 static void store(void *addr, T val);
34                 static T load(const void *addr);
35         };
36
37         template <typename T>
38         struct useless<T, 1> {
39                 static void store(void *addr, T val) { store_8(addr, (uint8_t)val); }
40                 static T load(const void *addr) { return (T)load_8(addr); }
41         };
42
43         template <typename T>
44         struct useless<T, 2> {
45                 static void store(void *addr, T val) { store_16(addr, (uint16_t)val); }
46                 static T load(const void *addr) { return (T)load_16(addr); }
47         };
48
49         template <typename T>
50         struct useless<T, 4> {
51                 static void store(void *addr, T val) { store_32(addr, (uint32_t)val); }
52                 static T load(const void *addr) { return (T)load_32(addr); }
53         };
54
55         template <typename T>
56         struct useless<T, 8> {
57                 static void store(void *addr, T val) { store_64(addr, (uint64_t)val); }
58                 static T load(const void *addr) { return (T)load_64(addr); }
59         };
60
61         template <typename T>
62         struct var {
63                 var() { useless<T, sizeof(T)>::store(&value, 0); }
64                 var(T v) { useless<T, sizeof(T)>::store(&value, v); }
65                 var(var const& r) {
66                         value = r.value;
67                 }
68                 ~var() { }
69
70                 void operator = (T v) { useless<T, sizeof(T)>::store(&value, v); }
71                 T operator () () { return useless<T, sizeof(T)>::load(&value); }
72                 void operator += (T v) {
73                         useless<T, sizeof(T)>::store(&value,
74                                         useless<T, sizeof(T)>::load(&value) + v);
75                 }
76                 bool operator == (const struct var<T> v) const { return useless<T, sizeof(T)>::load(&value) == useless<T, sizeof(T)>::load(&v.value); }
77
78                 T value;
79         };
80
81         class backoff_t
82         {
83          public:
84                 typedef int debug_info_param;
85                 void yield(debug_info_param info) { }
86                 void yield() { }
87         };
88
89
90         typedef backoff_t backoff;
91         typedef backoff_t linear_backoff;
92         typedef backoff_t exp_backoff;
93
94 }
95
96 #endif /* __UNRELACY_H__ */