P99
Main Page
Related Pages
Modules
Data Structures
Data Structures
Data Structure Index
Data Fields
All
a
c
d
e
f
i
l
m
n
r
s
t
w
Functions
c
e
f
i
n
r
Variables
Typedefs
Related Functions
Files
File List
Globals
All
0
1
2
3
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
Functions
_
a
b
c
d
e
f
i
j
l
m
n
p
r
s
t
u
v
w
Variables
Typedefs
_
b
c
d
e
f
i
l
m
o
p
r
s
t
u
v
Enumerations
Enumerator
Macros
0
1
2
3
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
Examples
•
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Modules
Pages
p99
p99_atomic_gcc_sync.h
Go to the documentation of this file.
1
/* This may look like nonsense, but it really is -*- mode: C; coding: utf-8 -*- */
2
/* */
3
/* Except for parts copied from previous work and as explicitly stated below, */
4
/* the author and copyright holder for this work is */
5
/* (C) copyright 2012, 2014 Jens Gustedt, INRIA, France */
6
/* */
7
/* This file is free software; it is part of the P99 project. */
8
/* */
9
/* Licensed under the Apache License, Version 2.0 (the "License"); */
10
/* you may not use this file except in compliance with the License. */
11
/* You may obtain a copy of the License at */
12
/* */
13
/* http://www.apache.org/licenses/LICENSE-2.0 */
14
/* */
15
/* Unless required by applicable law or agreed to in writing, software */
16
/* distributed under the License is distributed on an "AS IS" BASIS, */
17
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
18
/* See the License for the specific language governing permissions and */
19
/* limitations under the License. */
20
/* */
21
#ifndef P99_ATOMIC_GCC_SYNC_H
22
#define P99_ATOMIC_GCC_SYNC_H 1
23
24
#ifndef P99_ATOMIC_H
25
# warning "never include this file directly, use p99_atomic.h, instead"
26
#endif
27
28
#include "
p99_args.h
"
29
37
#define p00_atomic_exchange_n_(PTR, DES, ORD, ...) \
38
p99_extension ({ \
39
P99_MACRO_PVAR(p00_ptr, (PTR), volatile); \
40
P99_MACRO_VAR(p00_des, (DES)); \
41
register __typeof__(*(PTR)) p00_ret = p00_des; \
42
for (;;) { \
43
register __typeof__(*(PTR)) p00_val = __sync_val_compare_and_swap(p00_ptr, p00_ret, p00_des); \
44
if (P99_LIKELY(p00_val == p00_ret)) break; \
45
p00_ret = p00_val; \
46
} \
47
p00_ret = p00_ret; \
48
})
49
50
#define p00_atomic_exchange_n(...) p00_atomic_exchange_n_(__VA_ARGS__,,)
51
52
#define p00_mfence(...) __sync_synchronize()
53
54
#define p00_sync_lock_release_(OBJ, ORD, ...) \
55
p99_extension ({ \
56
P99_MACRO_PVAR(p00_obj, (OBJ), volatile); \
57
/* __sync_lock_release only has release consistency */
\
58
/* the fence must come before so nothing can be reordered after */
\
59
switch (ORD) { \
60
case memory_order_consume: ; \
61
case memory_order_acquire: ; \
62
case memory_order_acq_rel: ; \
63
case memory_order_seq_cst: ; \
64
p00_mfence(); \
65
} \
66
__sync_lock_release(p00_obj); \
67
})
68
69
#define p00_sync_lock_test_and_set_(OBJ, ORD, ...) \
70
p99_extension ({ \
71
P99_MACRO_PVAR(p00_obj, (OBJ), volatile); \
72
/* __sync_lock_test_and_set only has acquire consistency */
\
73
int ret = __sync_lock_test_and_set(p00_obj, 1); \
74
/* the fence must come after so nothing can be reordered before */
\
75
switch (ORD) { \
76
case memory_order_consume: ; \
77
case memory_order_release: ; \
78
case memory_order_acq_rel: ; \
79
case memory_order_seq_cst: ; \
80
p00_mfence(); \
81
} \
82
ret = ret; \
83
})
84
85
#define p00_sync_lock_release(...) p00_sync_lock_release_(__VA_ARGS__, memory_order_seq_cst, )
86
#define p00_sync_lock_test_and_set(...) p00_sync_lock_test_and_set_(__VA_ARGS__, memory_order_seq_cst, )
87
88
#define p00_atomic_compare_exchange_n_(PTR, EXP, DES, WEAK, SUC, FAI, ...) \
89
p99_extension ({ \
90
P99_MACRO_PVAR(p00_ptr, (PTR), volatile); \
91
P99_MACRO_VAR(p00_exp, (EXP)); \
92
P99_MACRO_VAR(p00_des, (DES), const); \
93
__typeof__(*PTR) p00_val = __sync_val_compare_and_swap(p00_ptr, *p00_exp, p00_des); \
94
_Bool p00_ret = (*p00_exp == p00_val); \
95
if (!p00_ret) *p00_exp = p00_val; \
96
p00_ret = p00_ret; \
97
})
98
99
#define p00_atomic_compare_exchange_n(...) \
100
P99_IF_EQ(P99_NARG(__VA_ARGS__), 3) \
101
(p00_atomic_compare_exchange_n_(__VA_ARGS__, 0, memory_order_seq_cst, memory_order_seq_cst)) \
102
(p00_atomic_compare_exchange_n_(__VA_ARGS__, memory_order_seq_cst, memory_order_seq_cst, ))
103
104
#define p00_atomic_load_n_(PTR, ORD, ...) \
105
p99_extension ({ \
106
P99_MACRO_PVAR(p00_ptr, (PTR), volatile); \
107
/* Ensure synchronization with all stores before */
\
108
switch (ORD) { \
109
case memory_order_consume:; \
110
case memory_order_acquire:; \
111
case memory_order_acq_rel:; \
112
(void)__sync_bool_compare_and_swap(p00_ptr, 0, 0); \
113
break; \
114
case memory_order_seq_cst:; \
115
p00_mfence(); \
116
} \
117
/* now ensure the load of the correct value */
\
118
register __typeof__(*(PTR)) const p00_ret = *p00_ptr; \
119
/* Inhibit reordering with all code after */
\
120
P99_MARK("load boundary for " P99_STRINGIFY(PTR)); \
121
p00_ret; \
122
})
123
124
#define p00_atomic_load_n(...) p00_atomic_load_n_(__VA_ARGS__,,)
125
126
#define p00_atomic_store_n_(PTR, DES, ORD, ...) \
127
p99_extension ({ \
128
P99_MACRO_PVAR(p00_ptr, (PTR), volatile); \
129
P99_MACRO_VAR(p00_des, (DES), const); \
130
/* Inhibit reordering with all code before */
\
131
P99_MARK("store boundary for " P99_STRINGIFY(PTR)); \
132
/* now ensure the store of the correct value */
\
133
*p00_ptr = p00_des; \
134
/* Ensure that store is visible for all code hereafter */
\
135
switch (ORD) { \
136
case memory_order_consume:; \
137
case memory_order_release:; \
138
case memory_order_acq_rel:; \
139
(void)__sync_bool_compare_and_swap(p00_ptr, p00_des, p00_des); \
140
break; \
141
case memory_order_seq_cst:; \
142
p00_mfence(); \
143
} \
144
})
145
146
#define p00_atomic_store_n(...) p00_atomic_store_n_(__VA_ARGS__, memory_order_seq_cst,)
147
148
149
#define p00_atomic_fetch_add_(PTR, VAL, ORD, ...) __sync_fetch_and_add((PTR), (VAL))
150
#define p00_atomic_fetch_add(...) p00_atomic_fetch_add_(__VA_ARGS__, ,)
151
#define p00_atomic_fetch_and_(PTR, VAL, ORD, ...) __sync_fetch_and_and((PTR), (VAL))
152
#define p00_atomic_fetch_and(...) p00_atomic_fetch_and_(__VA_ARGS__, ,)
153
#define p00_atomic_fetch_or_(PTR, VAL, ORD, ...) __sync_fetch_and_or((PTR), (VAL))
154
#define p00_atomic_fetch_or(...) p00_atomic_fetch_or_(__VA_ARGS__, ,)
155
#define p00_atomic_fetch_sub_(PTR, VAL, ORD, ...) __sync_fetch_and_sub((PTR), (VAL))
156
#define p00_atomic_fetch_sub(...) p00_atomic_fetch_sub_(__VA_ARGS__, ,)
157
#define p00_atomic_fetch_xor_(PTR, VAL, ORD, ...) __sync_fetch_and_xor((PTR), (VAL))
158
#define p00_atomic_fetch_xor(...) p00_atomic_fetch_xor_(__VA_ARGS__, ,)
159
160
161
#endif
p99_args.h
Providing macros that handle variadic macro argument lists.
Generated by
1.8.17