Halide 16.0.0
Halide compiler and libraries
Loading...
Searching...
No Matches
runtime_atomics.h
Go to the documentation of this file.
1#ifndef HALIDE_RUNTIME_RUNTIME_ATOMICS_H
2#define HALIDE_RUNTIME_RUNTIME_ATOMICS_H
3
4// This file provides an abstraction layer over the __sync/__atomic builtins
5// in Clang; for various reasons, we use __sync for 32-bit targets, and
6// __atomic for 64-bit. At some point it may be desirable/necessary to
7// migrate 32-bit to __atomic as well, at which time this file can
8// likely go away. See https://github.com/halide/Halide/issues/7431 for
9// a discussion of the history and issues as to why we work this way.
10
11#include "HalideRuntime.h"
12
13namespace Halide {
14namespace Runtime {
15namespace Internal {
16namespace Synchronization {
17
18namespace {
19
20// TODO: most of these wrappers should do the remove_volatile for secondary arguments;
21// I've only put it in place for the locations necessary at this time.
22template<class T>
23struct remove_volatile { typedef T type; };
24template<class T>
25struct remove_volatile<volatile T> { typedef T type; };
26
27#ifdef BITS_32
29 return __sync_and_and_fetch(addr, val);
30}
31
32template<typename T>
34 return __sync_fetch_and_add(addr, val);
35}
36
39 return __sync_fetch_and_add(addr, val);
40}
41
44 return __sync_fetch_and_sub(addr, val);
45}
46
49 return __sync_fetch_and_or(addr, val);
50}
51
52template<typename T>
54 return __sync_add_and_fetch(addr, val);
55}
56
57template<typename T>
59 return __sync_sub_and_fetch(addr, val);
60}
61
67 return oldval == gotval;
68}
69
72}
73
77}
78
81}
82
83template<typename T>
86}
87
90}
91
94}
95
96template<typename T>
98 return __sync_fetch_and_and(addr, val);
99}
100
103 return __sync_fetch_and_and(addr, val);
104}
105
106template<typename T>
107ALWAYS_INLINE void atomic_load_relaxed(T *addr, T *val) {
108 *val = *addr;
109}
110
111template<typename T>
112ALWAYS_INLINE void atomic_load_acquire(T *addr, T *val) {
114 *val = *addr;
115}
116
117template<typename T>
118ALWAYS_INLINE T atomic_exchange_acquire(T *addr, T val) {
119 // Despite the name, this is really just an exchange operation with acquire ordering.
120 return __sync_lock_test_and_set(addr, val);
121}
122
124 return __sync_or_and_fetch(addr, val);
125}
126
128 *addr = *val;
129}
130
131template<typename T>
132ALWAYS_INLINE void atomic_store_release(T *addr, T *val) {
133 *addr = *val;
135}
136
139 *addr = *val;
141}
142
145}
146
149}
150
151#else
152
154 return __atomic_and_fetch(addr, val, __ATOMIC_RELEASE);
155}
156
157template<typename T>
159 return __atomic_fetch_add(addr, val, __ATOMIC_ACQ_REL);
160}
161
164 return __atomic_fetch_add(addr, val, __ATOMIC_SEQ_CST);
165}
166
169 return __atomic_fetch_sub(addr, val, __ATOMIC_SEQ_CST);
170}
171
174 return __atomic_fetch_or(addr, val, __ATOMIC_SEQ_CST);
175}
176
177template<typename T>
179 return __atomic_add_fetch(addr, val, __ATOMIC_SEQ_CST);
180}
181
182template<typename T>
184 return __atomic_sub_fetch(addr, val, __ATOMIC_SEQ_CST);
185}
186
189}
190
194}
195
196template<typename T>
199}
200
203}
204
207}
208
211}
212
213template<typename T>
215 return __atomic_fetch_and(addr, val, __ATOMIC_RELEASE);
216}
217
220 return __atomic_fetch_and(addr, val, __ATOMIC_SEQ_CST);
221}
222
223template<typename T>
224ALWAYS_INLINE void atomic_load_relaxed(T *addr, T *val) {
226}
227
228template<typename T>
229ALWAYS_INLINE void atomic_load_acquire(T *addr, T *val) {
232 *val = *addr;
233}
234
235template<typename T>
236ALWAYS_INLINE T atomic_exchange_acquire(T *addr, T val) {
237 T result;
238 __atomic_exchange(addr, &val, &result, __ATOMIC_ACQUIRE);
239 return result;
240}
241
243 return __atomic_or_fetch(addr, val, __ATOMIC_RELAXED);
244}
245
248}
249
250template<typename T>
251ALWAYS_INLINE void atomic_store_release(T *addr, T *val) {
253}
254
258}
259
262}
263
266}
267
268#endif
269
270} // namespace
271
272} // namespace Synchronization
273} // namespace Internal
274} // namespace Runtime
275} // namespace Halide
276
277#endif // HALIDE_RUNTIME_RUNTIME_ATOMICS_H
This file declares the routines used by Halide internally in its runtime.
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
@ Internal
Not visible externally, similar to 'static' linkage in C.
Expr cast(Expr a)
Cast an expression to the halide type corresponding to the C++ type T.
Definition IROperator.h:358
__UINTPTR_TYPE__ uintptr_t
#define ALWAYS_INLINE