-
Notifications
You must be signed in to change notification settings - Fork 1
/
atomic.h
146 lines (118 loc) · 4.57 KB
/
atomic.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <stddef.h>
// To transform this into a builtin and communicate directly with WP,
// have a look to the WP manual, particularly on the drivers part
/*@
axiomatic thread_variables_properties{
logic integer MAX_THREAD reads \nothing;
axiom some_threads: 0 < MAX_THREAD;
}
predicate valid_thread_id(integer th) =
0 <= th < MAX_THREAD;
*/
//@ ghost size_t world;
/*@
assigns world;
ensures valid_thread_id(\result);
atomic \true ;
*/
size_t some_thread();
#define need_atomic_load(TYPE) \
/*@ \
requires \valid(loc); \
assigns \nothing; \
ensures \result == *loc; \
atomic \true; \
*/ \
TYPE atomic_load_##TYPE(TYPE volatile* loc)
#define atomic_load(TYPE, loc) atomic_load_##TYPE(loc)
#define need_atomic_store(TYPE) \
/*@ \
requires \valid(loc); \
assigns *loc; \
ensures *loc == des; \
atomic \true; \
*/ \
void atomic_store_##TYPE(TYPE volatile* loc, TYPE des)
#define atomic_store(TYPE, loc, des) atomic_store_##TYPE(loc, des)
#define need_atomic_compare_exchange(TYPE) \
/*@ \
requires \valid(loc) && \valid(exp); \
assigns *loc, *exp; \
atomic \true ; \
ensures \result == 1 || \result == 0; \
behavior succeed: \
assumes *exp == *loc; \
ensures \result == 1; \
ensures *loc == des ; \
ensures *exp == \old(*exp) ; \
behavior failed: \
assumes *exp != *loc; \
ensures \result == 0; \
ensures *loc == \old(*loc) ; \
ensures *exp == \old(*loc) ; \
disjoint behaviors ; \
complete behaviors ; \
*/ \
int atomic_compare_exchange_strong_##TYPE(TYPE volatile* loc, TYPE* exp, TYPE des)
#define atomic_compare_exchange(TYPE, loc, exp, des) atomic_compare_exchange_strong_##TYPE(loc, exp, des)
#define need_atomic_exchange(TYPE) \
/*@ \
requires \valid(loc); \
assigns *loc; \
ensures \result == \old(*loc); \
ensures *loc == des; \
atomic \true; \
*/ \
TYPE atomic_exchange_strong_##TYPE(TYPE volatile* loc, TYPE des)
#define atomic_exchange(TYPE, loc, des) atomic_exchange_strong_##TYPE(loc, des)
#define need_atomic_fetch_add(TYPE) \
/*@ \
requires \valid(loc); \
assigns *loc; \
ensures *loc == (int) \result + val; \
ensures \result == \old(*loc); \
atomic \true; \
*/ \
TYPE atomic_fetch_add_##TYPE(TYPE volatile* loc, TYPE val)
#define atomic_fetch_add(TYPE, loc, val) atomic_fetch_add_##TYPE(loc, val)
#define need_atomic_fetch_sub(TYPE) \
/*@ \
requires \valid(loc); \
assigns *loc; \
ensures *loc == (int) \result - val; \
ensures \result == \old(*loc); \
atomic \true; \
*/ \
TYPE atomic_fetch_sub_##TYPE(TYPE volatile* loc, TYPE val)
#define atomic_fetch_sub(TYPE, loc, val) atomic_fetch_sub_##TYPE(loc, val)
#define need_atomic_fetch_or(TYPE) \
/*@ \
requires \valid(loc); \
assigns *loc; \
ensures *loc == ((int) \result | val); \
ensures \result == \old(*loc); \
atomic \true; \
*/ \
TYPE atomic_fetch_or_##TYPE(TYPE volatile* loc, TYPE val)
#define atomic_fetch_or(TYPE, loc, val) atomic_fetch_or_##TYPE(loc, val)
#define need_atomic_fetch_xor(TYPE) \
/*@ \
requires \valid(loc); \
assigns *loc; \
ensures *loc == ((int) \result ^ val); \
ensures \result == \old(*loc); \
atomic \true; \
*/ \
TYPE atomic_fetch_xor_##TYPE(TYPE volatile* loc, TYPE val)
#define atomic_fetch_xor(TYPE, loc, val) atomic_fetch_xor_##TYPE(loc, val)
#define need_atomic_fetch_and(TYPE) \
/*@ \
requires \valid(loc); \
assigns *loc; \
ensures *loc == ((int) \result & val); \
ensures \result == \old(*loc); \
atomic \true; \
*/ \
TYPE atomic_fetch_and_##TYPE(TYPE volatile* loc, TYPE val)
#define atomic_fetch_and(TYPE, loc, val) atomic_fetch_and_##TYPE(loc, val)
#define ATOMIC(x) /*@ atomic \true; */{ x }