Halide 17.0.1
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 {
24 typedef T type;
25};
26template<class T>
27struct remove_volatile<volatile T> {
28 typedef T type;
29};
30
31#ifdef BITS_32
33 return __sync_and_and_fetch(addr, val);
34}
35
36template<typename T>
38 return __sync_fetch_and_add(addr, val);
39}
40
43 return __sync_fetch_and_add(addr, val);
44}
45
48 return __sync_fetch_and_sub(addr, val);
49}
50
53 return __sync_fetch_and_or(addr, val);
54}
55
56template<typename T>
58 return __sync_add_and_fetch(addr, val);
59}
60
61template<typename T>
63 return __sync_sub_and_fetch(addr, val);
64}
65
71 return oldval == gotval;
72}
73
76}
77
81}
82
85}
86
87template<typename T>
90}
91
94}
95
98}
99
100template<typename T>
101ALWAYS_INLINE T atomic_fetch_and_release(T *addr, T val) {
102 return __sync_fetch_and_and(addr, val);
103}
104
107 return __sync_fetch_and_and(addr, val);
108}
109
110template<typename T>
111ALWAYS_INLINE void atomic_load_relaxed(T *addr, T *val) {
112 *val = *addr;
113}
114
115template<typename T>
116ALWAYS_INLINE void atomic_load_acquire(T *addr, T *val) {
118 *val = *addr;
119}
120
121template<typename T>
122ALWAYS_INLINE T atomic_exchange_acquire(T *addr, T val) {
123 // Despite the name, this is really just an exchange operation with acquire ordering.
124 return __sync_lock_test_and_set(addr, val);
125}
126
128 return __sync_or_and_fetch(addr, val);
129}
130
132 *addr = *val;
133}
134
135template<typename T>
136ALWAYS_INLINE void atomic_store_release(T *addr, T *val) {
137 *addr = *val;
139}
140
143 *addr = *val;
145}
146
149}
150
153}
154
155#else
156
158 return __atomic_and_fetch(addr, val, __ATOMIC_RELEASE);
159}
160
161template<typename T>
163 return __atomic_fetch_add(addr, val, __ATOMIC_ACQ_REL);
164}
165
168 return __atomic_fetch_add(addr, val, __ATOMIC_SEQ_CST);
169}
170
173 return __atomic_fetch_sub(addr, val, __ATOMIC_SEQ_CST);
174}
175
178 return __atomic_fetch_or(addr, val, __ATOMIC_SEQ_CST);
179}
180
181template<typename T>
183 return __atomic_add_fetch(addr, val, __ATOMIC_SEQ_CST);
184}
185
186template<typename T>
188 return __atomic_sub_fetch(addr, val, __ATOMIC_SEQ_CST);
189}
190
193}
194
198}
199
200template<typename T>
203}
204
207}
208
211}
212
215}
216
217template<typename T>
219 return __atomic_fetch_and(addr, val, __ATOMIC_RELEASE);
220}
221
224 return __atomic_fetch_and(addr, val, __ATOMIC_SEQ_CST);
225}
226
227template<typename T>
228ALWAYS_INLINE void atomic_load_relaxed(T *addr, T *val) {
230}
231
232template<typename T>
233ALWAYS_INLINE void atomic_load_acquire(T *addr, T *val) {
236 *val = *addr;
237}
238
239template<typename T>
240ALWAYS_INLINE T atomic_exchange_acquire(T *addr, T val) {
241 T result;
242 __atomic_exchange(addr, &val, &result, __ATOMIC_ACQUIRE);
243 return result;
244}
245
247 return __atomic_or_fetch(addr, val, __ATOMIC_RELAXED);
248}
249
252}
253
254template<typename T>
255ALWAYS_INLINE void atomic_store_release(T *addr, T *val) {
257}
258
262}
263
266}
267
270}
271
272#endif
273
274} // namespace
275
276} // namespace Synchronization
277} // namespace Internal
278} // namespace Runtime
279} // namespace Halide
280
281#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:364
__UINTPTR_TYPE__ uintptr_t
#define ALWAYS_INLINE