Skip to content

Commit 23a2c0b

Browse files
committed
pythongh-108337: Add pyatomic.h header
This adds a new header that provides atomic operations on common data types. The intention is that this will be exposed through Python.h, although that is not the case yet. The only immediate use is in the test file.
1 parent d63972e commit 23a2c0b

15 files changed

+2914
-4
lines changed

Include/internal/pycore_atomic.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#ifndef Py_ATOMIC_H
2-
#define Py_ATOMIC_H
1+
#ifndef Py_INTERNAL_ATOMIC_H
2+
#define Py_INTERNAL_ATOMIC_H
33
#ifdef __cplusplus
44
extern "C" {
55
#endif
@@ -554,4 +554,4 @@ typedef struct _Py_atomic_int {
554554
#ifdef __cplusplus
555555
}
556556
#endif
557-
#endif /* Py_ATOMIC_H */
557+
#endif /* Py_INTERNAL_ATOMIC_H */

Include/pyatomic.h

Lines changed: 372 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,372 @@
1+
#ifndef Py_ATOMIC_H
2+
#define Py_ATOMIC_H
3+
4+
static inline int
5+
_Py_atomic_add_int(volatile int *address, int value);
6+
7+
static inline int8_t
8+
_Py_atomic_add_int8(volatile int8_t *address, int8_t value);
9+
10+
static inline int16_t
11+
_Py_atomic_add_int16(volatile int16_t *address, int16_t value);
12+
13+
static inline int32_t
14+
_Py_atomic_add_int32(volatile int32_t *address, int32_t value);
15+
16+
static inline int64_t
17+
_Py_atomic_add_int64(volatile int64_t *address, int64_t value);
18+
19+
static inline intptr_t
20+
_Py_atomic_add_intptr(volatile intptr_t *address, intptr_t value);
21+
22+
static inline unsigned int
23+
_Py_atomic_add_uint(volatile unsigned int *address, unsigned int value);
24+
25+
static inline uint8_t
26+
_Py_atomic_add_uint8(volatile uint8_t *address, uint8_t value);
27+
28+
static inline uint16_t
29+
_Py_atomic_add_uint16(volatile uint16_t *address, uint16_t value);
30+
31+
static inline uint32_t
32+
_Py_atomic_add_uint32(volatile uint32_t *address, uint32_t value);
33+
34+
static inline uint64_t
35+
_Py_atomic_add_uint64(volatile uint64_t *address, uint64_t value);
36+
37+
static inline uintptr_t
38+
_Py_atomic_add_uintptr(volatile uintptr_t *address, uintptr_t value);
39+
40+
static inline Py_ssize_t
41+
_Py_atomic_add_ssize(volatile Py_ssize_t *address, Py_ssize_t value);
42+
43+
44+
static inline int
45+
_Py_atomic_compare_exchange_int(volatile int *address, int expected, int value);
46+
47+
static inline int
48+
_Py_atomic_compare_exchange_int8(volatile int8_t *address, int8_t expected, int8_t value);
49+
50+
static inline int
51+
_Py_atomic_compare_exchange_int16(volatile int16_t *address, int16_t expected, int16_t value);
52+
53+
static inline int
54+
_Py_atomic_compare_exchange_int32(volatile int32_t *address, int32_t expected, int32_t value);
55+
56+
static inline int
57+
_Py_atomic_compare_exchange_int64(volatile int64_t *address, int64_t expected, int64_t value);
58+
59+
static inline int
60+
_Py_atomic_compare_exchange_intptr(volatile intptr_t *address, intptr_t expected, intptr_t value);
61+
62+
static inline int
63+
_Py_atomic_compare_exchange_uint(volatile unsigned int *address, unsigned int expected, unsigned int value);
64+
65+
static inline int
66+
_Py_atomic_compare_exchange_uint8(volatile uint8_t *address, uint8_t expected, uint8_t value);
67+
68+
static inline int
69+
_Py_atomic_compare_exchange_uint16(volatile uint16_t *address, uint16_t expected, uint16_t value);
70+
71+
static inline int
72+
_Py_atomic_compare_exchange_uint32(volatile uint32_t *address, uint32_t expected, uint32_t value);
73+
74+
static inline int
75+
_Py_atomic_compare_exchange_uint64(volatile uint64_t *address, uint64_t expected, uint64_t value);
76+
77+
static inline int
78+
_Py_atomic_compare_exchange_uintptr(volatile uintptr_t *address, uintptr_t expected, uintptr_t value);
79+
80+
static inline int
81+
_Py_atomic_compare_exchange_ssize(volatile Py_ssize_t *address, Py_ssize_t expected, Py_ssize_t value);
82+
83+
static inline int
84+
_Py_atomic_compare_exchange_ptr(volatile void *address, void *expected, void *value);
85+
86+
87+
static inline int
88+
_Py_atomic_exchange_int(volatile int *address, int value);
89+
90+
static inline int8_t
91+
_Py_atomic_exchange_int8(volatile int8_t *address, int8_t value);
92+
93+
static inline int16_t
94+
_Py_atomic_exchange_int16(volatile int16_t *address, int16_t value);
95+
96+
static inline int32_t
97+
_Py_atomic_exchange_int32(volatile int32_t *address, int32_t value);
98+
99+
static inline int64_t
100+
_Py_atomic_exchange_int64(volatile int64_t *address, int64_t value);
101+
102+
static inline intptr_t
103+
_Py_atomic_exchange_intptr(volatile intptr_t *address, intptr_t value);
104+
105+
static inline unsigned int
106+
_Py_atomic_exchange_uint(volatile unsigned int *address, unsigned int value);
107+
108+
static inline uint8_t
109+
_Py_atomic_exchange_uint8(volatile uint8_t *address, uint8_t value);
110+
111+
static inline uint16_t
112+
_Py_atomic_exchange_uint16(volatile uint16_t *address, uint16_t value);
113+
114+
static inline uint32_t
115+
_Py_atomic_exchange_uint32(volatile uint32_t *address, uint32_t value);
116+
117+
static inline uint64_t
118+
_Py_atomic_exchange_uint64(volatile uint64_t *address, uint64_t value);
119+
120+
static inline uintptr_t
121+
_Py_atomic_exchange_uintptr(volatile uintptr_t *address, uintptr_t value);
122+
123+
static inline Py_ssize_t
124+
_Py_atomic_exchange_ssize(volatile Py_ssize_t *address, Py_ssize_t value);
125+
126+
static inline void *
127+
_Py_atomic_exchange_ptr(volatile void *address, void *value);
128+
129+
130+
static inline uint8_t
131+
_Py_atomic_and_uint8(volatile uint8_t *address, uint8_t value);
132+
133+
static inline uint16_t
134+
_Py_atomic_and_uint16(volatile uint16_t *address, uint16_t value);
135+
136+
static inline uint32_t
137+
_Py_atomic_and_uint32(volatile uint32_t *address, uint32_t value);
138+
139+
static inline uint64_t
140+
_Py_atomic_and_uint64(volatile uint64_t *address, uint64_t value);
141+
142+
static inline uintptr_t
143+
_Py_atomic_and_uintptr(volatile uintptr_t *address, uintptr_t value);
144+
145+
146+
static inline uint8_t
147+
_Py_atomic_or_uint8(volatile uint8_t *address, uint8_t value);
148+
149+
static inline uint16_t
150+
_Py_atomic_or_uint16(volatile uint16_t *address, uint16_t value);
151+
152+
static inline uint32_t
153+
_Py_atomic_or_uint32(volatile uint32_t *address, uint32_t value);
154+
155+
static inline uint64_t
156+
_Py_atomic_or_uint64(volatile uint64_t *address, uint64_t value);
157+
158+
static inline uintptr_t
159+
_Py_atomic_or_uintptr(volatile uintptr_t *address, uintptr_t value);
160+
161+
162+
static inline int
163+
_Py_atomic_load_int(const volatile int *address);
164+
165+
static inline int8_t
166+
_Py_atomic_load_int8(const volatile int8_t *address);
167+
168+
static inline int16_t
169+
_Py_atomic_load_int16(const volatile int16_t *address);
170+
171+
static inline int32_t
172+
_Py_atomic_load_int32(const volatile int32_t *address);
173+
174+
static inline int64_t
175+
_Py_atomic_load_int64(const volatile int64_t *address);
176+
177+
static inline intptr_t
178+
_Py_atomic_load_intptr(const volatile intptr_t *address);
179+
180+
static inline uint8_t
181+
_Py_atomic_load_uint8(const volatile uint8_t *address);
182+
183+
static inline uint16_t
184+
_Py_atomic_load_uint16(const volatile uint16_t *address);
185+
186+
static inline uint32_t
187+
_Py_atomic_load_uint32(const volatile uint32_t *address);
188+
189+
static inline uint64_t
190+
_Py_atomic_load_uint64(const volatile uint64_t *address);
191+
192+
static inline uintptr_t
193+
_Py_atomic_load_uintptr(const volatile uintptr_t *address);
194+
195+
static inline unsigned int
196+
_Py_atomic_load_uint(const volatile unsigned int *address);
197+
198+
static inline Py_ssize_t
199+
_Py_atomic_load_ssize(const volatile Py_ssize_t *address);
200+
201+
static inline void *
202+
_Py_atomic_load_ptr(const volatile void *address);
203+
204+
205+
static inline int
206+
_Py_atomic_load_int_relaxed(const volatile int *address);
207+
208+
static inline int8_t
209+
_Py_atomic_load_int8_relaxed(const volatile int8_t *address);
210+
211+
static inline int16_t
212+
_Py_atomic_load_int16_relaxed(const volatile int16_t *address);
213+
214+
static inline int32_t
215+
_Py_atomic_load_int32_relaxed(const volatile int32_t *address);
216+
217+
static inline int64_t
218+
_Py_atomic_load_int64_relaxed(const volatile int64_t *address);
219+
220+
static inline intptr_t
221+
_Py_atomic_load_intptr_relaxed(const volatile intptr_t *address);
222+
223+
static inline uint8_t
224+
_Py_atomic_load_uint8_relaxed(const volatile uint8_t *address);
225+
226+
static inline uint16_t
227+
_Py_atomic_load_uint16_relaxed(const volatile uint16_t *address);
228+
229+
static inline uint32_t
230+
_Py_atomic_load_uint32_relaxed(const volatile uint32_t *address);
231+
232+
static inline uint64_t
233+
_Py_atomic_load_uint64_relaxed(const volatile uint64_t *address);
234+
235+
static inline uintptr_t
236+
_Py_atomic_load_uintptr_relaxed(const volatile uintptr_t *address);
237+
238+
static inline unsigned int
239+
_Py_atomic_load_uint_relaxed(const volatile unsigned int *address);
240+
241+
static inline Py_ssize_t
242+
_Py_atomic_load_ssize_relaxed(const volatile Py_ssize_t *address);
243+
244+
static inline void *
245+
_Py_atomic_load_ptr_relaxed(const volatile void *address);
246+
247+
248+
static inline void
249+
_Py_atomic_store_int(volatile int *address, int value);
250+
251+
static inline void
252+
_Py_atomic_store_int8(volatile int8_t *address, int8_t value);
253+
254+
static inline void
255+
_Py_atomic_store_int16(volatile int16_t *address, int16_t value);
256+
257+
static inline void
258+
_Py_atomic_store_int32(volatile int32_t *address, int32_t value);
259+
260+
static inline void
261+
_Py_atomic_store_int64(volatile int64_t *address, int64_t value);
262+
263+
static inline void
264+
_Py_atomic_store_intptr(volatile intptr_t *address, intptr_t value);
265+
266+
static inline void
267+
_Py_atomic_store_uint8(volatile uint8_t *address, uint8_t value);
268+
269+
static inline void
270+
_Py_atomic_store_uint16(volatile uint16_t *address, uint16_t value);
271+
272+
static inline void
273+
_Py_atomic_store_uint32(volatile uint32_t *address, uint32_t value);
274+
275+
static inline void
276+
_Py_atomic_store_uint64(volatile uint64_t *address, uint64_t value);
277+
278+
static inline void
279+
_Py_atomic_store_uintptr(volatile uintptr_t *address, uintptr_t value);
280+
281+
static inline void
282+
_Py_atomic_store_uint(volatile unsigned int *address, unsigned int value);
283+
284+
static inline void
285+
_Py_atomic_store_ptr(volatile void *address, void *value);
286+
287+
static inline void
288+
_Py_atomic_store_ssize(volatile Py_ssize_t* address, Py_ssize_t value);
289+
290+
291+
static inline void
292+
_Py_atomic_store_int_relaxed(volatile int *address, int value);
293+
294+
static inline void
295+
_Py_atomic_store_int8_relaxed(volatile int8_t *address, int8_t value);
296+
297+
static inline void
298+
_Py_atomic_store_int16_relaxed(volatile int16_t *address, int16_t value);
299+
300+
static inline void
301+
_Py_atomic_store_int32_relaxed(volatile int32_t *address, int32_t value);
302+
303+
static inline void
304+
_Py_atomic_store_int64_relaxed(volatile int64_t *address, int64_t value);
305+
306+
static inline void
307+
_Py_atomic_store_intptr_relaxed(volatile intptr_t *address, intptr_t value);
308+
309+
static inline void
310+
_Py_atomic_store_uint8_relaxed(volatile uint8_t* address, uint8_t value);
311+
312+
static inline void
313+
_Py_atomic_store_uint16_relaxed(volatile uint16_t *address, uint16_t value);
314+
315+
static inline void
316+
_Py_atomic_store_uint32_relaxed(volatile uint32_t *address, uint32_t value);
317+
318+
static inline void
319+
_Py_atomic_store_uint64_relaxed(volatile uint64_t *address, uint64_t value);
320+
321+
static inline void
322+
_Py_atomic_store_uintptr_relaxed(volatile uintptr_t *address, uintptr_t value);
323+
324+
static inline void
325+
_Py_atomic_store_uint_relaxed(volatile unsigned int *address, unsigned int value);
326+
327+
static inline void
328+
_Py_atomic_store_ptr_relaxed(volatile void *address, void *value);
329+
330+
static inline void
331+
_Py_atomic_store_ssize_relaxed(volatile Py_ssize_t *address, Py_ssize_t value);
332+
333+
334+
static inline void
335+
_Py_atomic_store_uint64_release(volatile uint64_t *address, uint64_t value);
336+
337+
static inline void
338+
_Py_atomic_store_ptr_release(volatile void *address, void *value);
339+
340+
341+
static inline void
342+
_Py_atomic_fence_seq_cst(void);
343+
344+
static inline void
345+
_Py_atomic_fence_release(void);
346+
347+
348+
#ifndef _Py_USE_GCC_BUILTIN_ATOMICS
349+
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
350+
#define _Py_USE_GCC_BUILTIN_ATOMICS 1
351+
#elif defined(__clang__)
352+
#if __has_builtin(__atomic_load)
353+
#define _Py_USE_GCC_BUILTIN_ATOMICS 1
354+
#endif
355+
#endif
356+
#endif
357+
358+
#if _Py_USE_GCC_BUILTIN_ATOMICS
359+
#define Py_ATOMIC_GCC_H
360+
#include "pyatomic_gcc.h"
361+
#elif __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
362+
#define Py_ATOMIC_STD_H
363+
#include "pyatomic_std.h"
364+
#elif defined(_MSC_VER)
365+
#define Py_ATOMIC_MSC_H
366+
#include "pyatomic_msc.h"
367+
#else
368+
#error "define pyatomic for this platform"
369+
#endif
370+
371+
#endif /* Py_ATOMIC_H */
372+

0 commit comments

Comments
 (0)