rlib
Convenience library for useful things
Loading...
Searching...
No Matches
ratomic.h
Go to the documentation of this file.
1/* RLIB - Convenience library for useful things
2 * Copyright (C) 2015 Haakon Sporsheim <haakon.sporsheim@gmail.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 3.0 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library.
16 * See the COPYING file at the root of the source repository.
17 */
18#ifndef __R_ATOMIC_H__
19#define __R_ATOMIC_H__
20
21#if !defined(__RLIB_H_INCLUDE_GUARD__) && !defined(RLIB_COMPILATION)
22#error "#include <rlib.h> only please."
23#endif
24
53#include <rlib/rtypes.h>
54
55/* Pick an atomics backend. USE_CLANG_ATOMICS uses __c11_atomic_*
56 * built-ins which only Clang provides -- GCC's __has_extension reports
57 * c_atomic = 1 (it supports C11 atomics via __atomic_*) but does not
58 * expose the __c11_atomic_* spellings, so __clang__ has to gate this
59 * arm explicitly. */
60#if defined(__clang__) && __has_extension(c_atomic)
61#define USE_CLANG_ATOMICS 1
62#elif R_GNUC_PREREQ(4, 9) && !defined(__STDC_NO_ATOMICS__)
63#define USE_GNUC_ATOMICS 1
64#elif defined(__GNUC__)
65#define USE_SYNC_ATOMICS 1
66#elif defined(_MSC_VER)
67#include <windows.h>
68#define USE_MSC_ATOMICS 1
69#endif
70
71
73
74#if defined(USE_CLANG_ATOMICS) || defined(USE_GNUC_ATOMICS)
76typedef _Atomic(int) raint;
78typedef _Atomic(ruint) rauint;
80typedef _Atomic(ruintptr) raptr;
81#elif defined(USE_MSC_ATOMICS)
82typedef int volatile raint;
83typedef ruint volatile rauint;
84typedef ruintptr volatile raptr;
85#else
86typedef int raint;
87typedef ruint rauint;
88typedef rpointer raptr;
89#endif
90
96typedef raint raboolean;
97
101R_API int r_atomic_int_load (raint * a);
103R_API void r_atomic_int_store (raint * a, int val);
105R_API int r_atomic_int_exchange (raint * a, int val);
113R_API rboolean r_atomic_int_cmp_xchg_weak (raint * a, int * old, int val);
115R_API rboolean r_atomic_int_cmp_xchg_strong (raint * a, int * old, int val);
117R_API int r_atomic_int_fetch_add (raint * a, int val);
119R_API int r_atomic_int_fetch_sub (raint * a, int val);
121R_API int r_atomic_int_fetch_and (raint * a, int val);
123R_API int r_atomic_int_fetch_or (raint * a, int val);
125R_API int r_atomic_int_fetch_xor (raint * a, int val);
135#define r_atomic_bool_load(a) ((rboolean) r_atomic_int_load (a))
137#define r_atomic_bool_store(a, v) r_atomic_int_store (a, (int) (v))
139#define r_atomic_bool_exchange(a, v) ((rboolean) r_atomic_int_exchange (a, (int) (v)))
141#define r_atomic_bool_set(a) r_atomic_bool_store (a, TRUE)
143#define r_atomic_bool_unset(a) r_atomic_bool_store (a, FALSE)
151R_API void r_atomic_uint_store (rauint * a, ruint val);
175R_API void r_atomic_ptr_store (raptr * a, rpointer val);
200R_END_DECLS
201
204#if defined(USE_CLANG_ATOMICS)
205#define r_atomic_int_load(a) __c11_atomic_load (a, __ATOMIC_SEQ_CST)
206#define r_atomic_int_store(a, v) __c11_atomic_store (a, v, __ATOMIC_SEQ_CST)
207#define r_atomic_int_exchange(a, v) __c11_atomic_exchange (a, v, __ATOMIC_SEQ_CST)
208#define r_atomic_int_cmp_xchg_weak(a, o, v) __c11_atomic_compare_exchange_weak (a, o, v, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
209#define r_atomic_int_cmp_xchg_strong(a, o, v) __c11_atomic_compare_exchange_strong (a, o, v, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
210#define r_atomic_int_fetch_add(a, v) __c11_atomic_fetch_add (a, v, __ATOMIC_SEQ_CST)
211#define r_atomic_int_fetch_sub(a, v) __c11_atomic_fetch_sub (a, v, __ATOMIC_SEQ_CST)
212#define r_atomic_int_fetch_and(a, v) __c11_atomic_fetch_and (a, v, __ATOMIC_SEQ_CST)
213#define r_atomic_int_fetch_or(a, v) __c11_atomic_fetch_or (a, v, __ATOMIC_SEQ_CST)
214#define r_atomic_int_fetch_xor(a, v) __c11_atomic_fetch_xor (a, v, __ATOMIC_SEQ_CST)
215
216#define r_atomic_uint_load(a) __c11_atomic_load (a, __ATOMIC_SEQ_CST)
217#define r_atomic_uint_store(a, v) __c11_atomic_store (a, v, __ATOMIC_SEQ_CST)
218#define r_atomic_uint_exchange(a, v) __c11_atomic_exchange (a, v, __ATOMIC_SEQ_CST)
219#define r_atomic_uint_cmp_xchg_weak(a, o, v) __c11_atomic_compare_exchange_weak (a, o, v, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
220#define r_atomic_uint_cmp_xchg_strong(a, o, v) __c11_atomic_compare_exchange_strong (a, o, v, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
221#define r_atomic_uint_fetch_add(a, v) __c11_atomic_fetch_add (a, v, __ATOMIC_SEQ_CST)
222#define r_atomic_uint_fetch_sub(a, v) __c11_atomic_fetch_sub (a, v, __ATOMIC_SEQ_CST)
223#define r_atomic_uint_fetch_and(a, v) __c11_atomic_fetch_and (a, v, __ATOMIC_SEQ_CST)
224#define r_atomic_uint_fetch_or(a, v) __c11_atomic_fetch_or (a, v, __ATOMIC_SEQ_CST)
225#define r_atomic_uint_fetch_xor(a, v) __c11_atomic_fetch_xor (a, v, __ATOMIC_SEQ_CST)
226
227#define r_atomic_ptr_load(a) (rpointer)__c11_atomic_load (a, __ATOMIC_SEQ_CST)
228#define r_atomic_ptr_store(a, v) __c11_atomic_store (a, (ruintptr)v, __ATOMIC_SEQ_CST)
229#define r_atomic_ptr_exchange(a, v) (rpointer)__c11_atomic_exchange (a, (ruintptr)v, __ATOMIC_SEQ_CST)
230#define r_atomic_ptr_cmp_xchg_weak(a, o, v) __c11_atomic_compare_exchange_weak (a, (ruintptr*)o, (ruintptr)v, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
231#define r_atomic_ptr_cmp_xchg_strong(a, o, v) __c11_atomic_compare_exchange_strong (a, (ruintptr*)o, (ruintptr)v, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
232#define r_atomic_ptr_fetch_add(a, v) (rpointer)__c11_atomic_fetch_add (a, (ruintptr)v, __ATOMIC_SEQ_CST)
233#define r_atomic_ptr_fetch_sub(a, v) (rpointer)__c11_atomic_fetch_sub (a, (ruintptr)v, __ATOMIC_SEQ_CST)
234#define r_atomic_ptr_fetch_and(a, v) (rpointer)__c11_atomic_fetch_and (a, (ruintptr)v, __ATOMIC_SEQ_CST)
235#define r_atomic_ptr_fetch_or(a, v) (rpointer)__c11_atomic_fetch_or (a, (ruintptr)v, __ATOMIC_SEQ_CST)
236#define r_atomic_ptr_fetch_xor(a, v) (rpointer)__c11_atomic_fetch_xor (a, (ruintptr)v, __ATOMIC_SEQ_CST)
237#elif defined(USE_GNUC_ATOMICS)
238#define r_atomic_int_load(a) __atomic_load_n (a, __ATOMIC_SEQ_CST)
239#define r_atomic_int_store(a, v) __atomic_store_n (a, v, __ATOMIC_SEQ_CST)
240#define r_atomic_int_exchange(a, v) __atomic_exchange_n (a, v, __ATOMIC_SEQ_CST)
241#define r_atomic_int_cmp_xchg_weak(a, o, v) __atomic_compare_exchange_n (a, o, v, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
242#define r_atomic_int_cmp_xchg_strong(a, o, v) __atomic_compare_exchange_n (a, o, v, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
243#define r_atomic_int_fetch_add(a, v) __atomic_fetch_add (a, v, __ATOMIC_SEQ_CST)
244#define r_atomic_int_fetch_sub(a, v) __atomic_fetch_sub (a, v, __ATOMIC_SEQ_CST)
245#define r_atomic_int_fetch_and(a, v) __atomic_fetch_and (a, v, __ATOMIC_SEQ_CST)
246#define r_atomic_int_fetch_or(a, v) __atomic_fetch_or (a, v, __ATOMIC_SEQ_CST)
247#define r_atomic_int_fetch_xor(a, v) __atomic_fetch_xor (a, v, __ATOMIC_SEQ_CST)
248
249#define r_atomic_uint_load(a) __atomic_load_n (a, __ATOMIC_SEQ_CST)
250#define r_atomic_uint_store(a, v) __atomic_store_n (a, v, __ATOMIC_SEQ_CST)
251#define r_atomic_uint_exchange(a, v) __atomic_exchange_n (a, v, __ATOMIC_SEQ_CST)
252#define r_atomic_uint_cmp_xchg_weak(a, o, v) __atomic_compare_exchange_n (a, o, v, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
253#define r_atomic_uint_cmp_xchg_strong(a, o, v) __atomic_compare_exchange_n (a, o, v, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
254#define r_atomic_uint_fetch_add(a, v) __atomic_fetch_add (a, v, __ATOMIC_SEQ_CST)
255#define r_atomic_uint_fetch_sub(a, v) __atomic_fetch_sub (a, v, __ATOMIC_SEQ_CST)
256#define r_atomic_uint_fetch_and(a, v) __atomic_fetch_and (a, v, __ATOMIC_SEQ_CST)
257#define r_atomic_uint_fetch_or(a, v) __atomic_fetch_or (a, v, __ATOMIC_SEQ_CST)
258#define r_atomic_uint_fetch_xor(a, v) __atomic_fetch_xor (a, v, __ATOMIC_SEQ_CST)
259
260#define r_atomic_ptr_load(a) (rpointer)__atomic_load_n (a, __ATOMIC_SEQ_CST)
261#define r_atomic_ptr_store(a, v) __atomic_store_n (a, (ruintptr)v, __ATOMIC_SEQ_CST)
262#define r_atomic_ptr_exchange(a, v) (rpointer)__atomic_exchange_n (a, (ruintptr)v, __ATOMIC_SEQ_CST)
263#define r_atomic_ptr_cmp_xchg_weak(a, o, v) __atomic_compare_exchange_n (a, (ruintptr*)o, (ruintptr)v, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
264#define r_atomic_ptr_cmp_xchg_strong(a, o, v) __atomic_compare_exchange_n (a, (ruintptr*)o, (ruintptr)v, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
265#define r_atomic_ptr_fetch_add(a, v) (rpointer)__atomic_fetch_add (a, (ruintptr)v, __ATOMIC_SEQ_CST)
266#define r_atomic_ptr_fetch_sub(a, v) (rpointer)__atomic_fetch_sub (a, (ruintptr)v, __ATOMIC_SEQ_CST)
267#define r_atomic_ptr_fetch_and(a, v) (rpointer)__atomic_fetch_and (a, (ruintptr)v, __ATOMIC_SEQ_CST)
268#define r_atomic_ptr_fetch_or(a, v) (rpointer)__atomic_fetch_or (a, (ruintptr)v, __ATOMIC_SEQ_CST)
269#define r_atomic_ptr_fetch_xor(a, v) (rpointer)__atomic_fetch_xor (a, (ruintptr)v, __ATOMIC_SEQ_CST)
270#elif defined(USE_SYNC_ATOMICS)
271#if __has_builtin(__sync_swap)
272#define r_atomic_exchange(a, v) __sync_swap(a, v)
273#else
274#define r_atomic_exchange(a, v) \
275__extension__ ({ \
276 __typeof__(a) __a = (a); \
277 __typeof__(v) __v = (v); \
278 __sync_synchronize(); \
279 __sync_lock_test_and_set(__a, __v); \
280})
281#endif
282#define r_atomic_cmp_xchg(a, o, v) \
283__extension__ ({ \
284 __typeof__(o) __op = (o); \
285 __typeof__(*o) __o = *__op; \
286 (rboolean)((*__op = __sync_val_compare_and_swap(a, __o, v)) == __o); \
287})
288
289#define r_atomic_int_load(a) __sync_fetch_and_add(a, 0)
290#define r_atomic_int_store(a, v) r_atomic_exchange (a, v)
291#define r_atomic_int_exchange(a, v) r_atomic_exchange (a, v)
292#define r_atomic_int_cmp_xchg_weak(a, o, v) r_atomic_cmp_xchg (a, o, v)
293#define r_atomic_int_cmp_xchg_strong(a, o, v) r_atomic_cmp_xchg (a, o, v)
294#define r_atomic_int_fetch_add(a, v) __sync_fetch_and_add (a, v)
295#define r_atomic_int_fetch_sub(a, v) __sync_fetch_and_sub (a, v)
296#define r_atomic_int_fetch_and(a, v) __sync_fetch_and_and (a, v)
297#define r_atomic_int_fetch_or(a, v) __sync_fetch_and_or (a, v)
298#define r_atomic_int_fetch_xor(a, v) __sync_fetch_and_xor (a, v)
299
300#define r_atomic_uint_load(a) __sync_fetch_and_add(a, 0)
301#define r_atomic_uint_store(a, v) r_atomic_exchange (a, v)
302#define r_atomic_uint_exchange(a, v) r_atomic_exchange (a, v)
303#define r_atomic_uint_cmp_xchg_weak(a, o, v) r_atomic_cmp_xchg (a, o, v)
304#define r_atomic_uint_cmp_xchg_strong(a, o, v) r_atomic_cmp_xchg (a, o, v)
305#define r_atomic_uint_fetch_add(a, v) __sync_fetch_and_add (a, v)
306#define r_atomic_uint_fetch_sub(a, v) __sync_fetch_and_sub (a, v)
307#define r_atomic_uint_fetch_and(a, v) __sync_fetch_and_and (a, v)
308#define r_atomic_uint_fetch_or(a, v) __sync_fetch_and_or (a, v)
309#define r_atomic_uint_fetch_xor(a, v) __sync_fetch_and_xor (a, v)
310
311#define r_atomic_ptr_load(a) (rpointer)__sync_fetch_and_add(a, 0)
312#define r_atomic_ptr_store(a, v) r_atomic_exchange (a, v)
313#define r_atomic_ptr_exchange(a, v) (rpointer)r_atomic_exchange (a, v)
314#define r_atomic_ptr_cmp_xchg_weak(a, o, v) r_atomic_cmp_xchg (a, o, v)
315#define r_atomic_ptr_cmp_xchg_strong(a, o, v) r_atomic_cmp_xchg (a, o, v)
316#define r_atomic_ptr_fetch_add(a, v) (rpointer)__sync_fetch_and_add (a, v)
317#define r_atomic_ptr_fetch_sub(a, v) (rpointer)__sync_fetch_and_sub (a, v)
318#define r_atomic_ptr_fetch_and(a, v) (rpointer)__sync_fetch_and_and (a, v)
319#define r_atomic_ptr_fetch_or(a, v) (rpointer)__sync_fetch_and_or (a, v)
320#define r_atomic_ptr_fetch_xor(a, v) (rpointer)__sync_fetch_and_xor (a, v)
321#elif USE_MSC_ATOMICS
322#include <intrin.h>
323
324#define r_atomic_int_load(a) (MemoryBarrier(), *a)
325#define r_atomic_int_store(a, v) _InterlockedExchange ((long volatile *)a, (long)v)
326#define r_atomic_int_exchange(a, v) _InterlockedExchange ((long volatile *)a, (long)v)
327/* C11 semantics: cmp_xchg writes the observed value back into *o on
328 * failure so the caller can retry against the up-to-date value. The
329 * MSVC intrinsics only return the prior value; emulate the write-back
330 * in tiny inline helpers (otherwise lock-free retry loops -- e.g.
331 * r_ref_weak_ref -- spin forever once *a diverges from the initial
332 * *o on the first attempt).
333 *
334 * The implementations live behind _impl-suffixed names and the public
335 * names are #define'd onto them, matching the macro-style indirection
336 * the rest of this header uses. That keeps ratomic.c's out-of-line
337 * fallbacks (which use the (parens-around-name) macro-suppression
338 * trick) free of name collisions on MSVC. */
339static inline rboolean _r_atomic_int_cmp_xchg_weak_impl (raint * a, int * o, int v) {
340 long prev = _InterlockedCompareExchange ((long volatile *)a, (long)v, (long)*o);
341 if (prev == (long)*o) return TRUE;
342 *o = (int)prev;
343 return FALSE;
344}
345#define r_atomic_int_cmp_xchg_weak(a, o, v) _r_atomic_int_cmp_xchg_weak_impl ((a), (o), (v))
346#define r_atomic_int_cmp_xchg_strong(a, o, v) r_atomic_int_cmp_xchg_weak (a, o, v)
347#define r_atomic_int_fetch_add(a, v) _InterlockedExchangeAdd ((long volatile *)a, (long)v)
348#define r_atomic_int_fetch_sub(a, v) _InterlockedExchangeAdd ((long volatile *)a, -((long)v))
349#define r_atomic_int_fetch_and(a, v) _InterlockedAnd ((long volatile *)a, (long)v)
350#define r_atomic_int_fetch_or(a, v) _InterlockedOr ((long volatile *)a, (long)v)
351#define r_atomic_int_fetch_xor(a, v) _InterlockedXor ((long volatile *)a, (long)v)
352
353#define r_atomic_uint_load(a) (MemoryBarrier(), *a)
354#define r_atomic_uint_store(a, v) _InterlockedExchange ((long volatile *)a, (long)v)
355#define r_atomic_uint_exchange(a, v) _InterlockedExchange ((long volatile *)a, (long)v)
356static inline rboolean _r_atomic_uint_cmp_xchg_weak_impl (rauint * a, ruint * o, ruint v) {
357 long prev = _InterlockedCompareExchange ((long volatile *)a, (long)v, (long)*o);
358 if ((ruint)prev == *o) return TRUE;
359 *o = (ruint)prev;
360 return FALSE;
361}
362#define r_atomic_uint_cmp_xchg_weak(a, o, v) _r_atomic_uint_cmp_xchg_weak_impl ((a), (o), (v))
363#define r_atomic_uint_cmp_xchg_strong(a, o, v) r_atomic_uint_cmp_xchg_weak (a, o, v)
364#define r_atomic_uint_fetch_add(a, v) _InterlockedExchangeAdd ((long volatile *)a, (long)v)
365#define r_atomic_uint_fetch_sub(a, v) _InterlockedExchangeAdd ((long volatile *)a, -((long)v))
366#define r_atomic_uint_fetch_and(a, v) _InterlockedAnd ((long volatile *)a, (long)v)
367#define r_atomic_uint_fetch_or(a, v) _InterlockedOr ((long volatile *)a, (long)v)
368#define r_atomic_uint_fetch_xor(a, v) _InterlockedXor ((long volatile *)a, (long)v)
369
370#define r_atomic_ptr_load(a) (rpointer)(MemoryBarrier(), *a)
371#define r_atomic_ptr_store(a, v) _InterlockedExchangePointer ((rpointer volatile)a, (rpointer)v)
372#define r_atomic_ptr_exchange(a, v) (rpointer)_InterlockedExchangePointer ((rpointer volatile)a, (rpointer)v)
373static inline rboolean _r_atomic_ptr_cmp_xchg_weak_impl (raptr * a, rpointer * o, rpointer v) {
374 rpointer prev = _InterlockedCompareExchangePointer ((rpointer volatile)a, v, *o);
375 if (prev == *o) return TRUE;
376 *o = prev;
377 return FALSE;
378}
379#define r_atomic_ptr_cmp_xchg_weak(a, o, v) _r_atomic_ptr_cmp_xchg_weak_impl ((a), (o), (rpointer)(v))
380#define r_atomic_ptr_cmp_xchg_strong(a, o, v) r_atomic_ptr_cmp_xchg_weak (a, o, v)
381#if RLIB_SIZEOF_VOID_P == 4
382#define r_atomic_ptr_fetch_add(a, v) (rpointer)_InterlockedExchangeAdd ((long volatile *)a, (long)v)
383#define r_atomic_ptr_fetch_sub(a, v) (rpointer)_InterlockedExchangeAdd ((long volatile *)a, -((long)v))
384#define r_atomic_ptr_fetch_and(a, v) (rpointer)_InterlockedAnd ((long volatile *)a, (long)v)
385#define r_atomic_ptr_fetch_or(a, v) (rpointer)_InterlockedOr ((long volatile *)a, (long)v)
386#define r_atomic_ptr_fetch_xor(a, v) (rpointer)_InterlockedXor ((long volatile *)a, (long)v)
387#elif RLIB_SIZEOF_VOID_P == 8
388#define r_atomic_ptr_fetch_add(a, v) (rpointer)_InterlockedExchangeAdd64 ((_int64 volatile *)a, (_int64)v)
389#define r_atomic_ptr_fetch_sub(a, v) (rpointer)_InterlockedExchangeAdd64 ((_int64 volatile *)a, -((_int64)v))
390#define r_atomic_ptr_fetch_and(a, v) (rpointer)_InterlockedAnd64 ((_int64 volatile *)a, (_int64)v)
391#define r_atomic_ptr_fetch_or(a, v) (rpointer)_InterlockedOr64 ((_int64 volatile *)a, (_int64)v)
392#define r_atomic_ptr_fetch_xor(a, v) (rpointer)_InterlockedXor64 ((_int64 volatile *)a, (_int64)v)
393#else
394#error only x86 and x86_64 with MSC supported
395#endif
396#endif
397
398#endif /* __R_ATOMIC_H__ */
void r_atomic_int_store(raint *a, int val)
Atomically store val into a.
rpointer r_atomic_ptr_fetch_sub(raptr *a, rpointer val)
Pointer-arithmetic fetch-sub; semantics mirror r_atomic_ptr_fetch_add.
int r_atomic_int_load(raint *a)
Atomically read a's value.
int r_atomic_int_fetch_sub(raint *a, int val)
Atomically compute *a -= val and return the previous *a.
void r_atomic_uint_store(rauint *a, ruint val)
Atomically store val into a.
rboolean r_atomic_uint_cmp_xchg_weak(rauint *a, ruint *old, ruint val)
Weak CAS; see r_atomic_int_cmp_xchg_weak for semantics.
ruint r_atomic_uint_exchange(rauint *a, ruint val)
Atomically write val and return the previous value.
rpointer r_atomic_ptr_fetch_and(raptr *a, rpointer val)
Bitwise &= over pointer storage (treat as integer width).
int r_atomic_int_fetch_xor(raint *a, int val)
Atomically compute *a ^= val and return the previous *a.
ruint r_atomic_uint_fetch_sub(rauint *a, ruint val)
Atomically compute *a -= val and return the previous *a.
rpointer r_atomic_ptr_load(raptr *a)
Atomically read a's pointer value.
ruint r_atomic_uint_fetch_and(rauint *a, ruint val)
Atomically compute *a &= val and return the previous *a.
rboolean r_atomic_ptr_cmp_xchg_strong(raptr *a, rpointer *old, rpointer val)
Strong CAS on pointer storage; no spurious failures.
int r_atomic_int_fetch_and(raint *a, int val)
Atomically compute *a &= val and return the previous *a.
rpointer r_atomic_ptr_fetch_xor(raptr *a, rpointer val)
Bitwise ^= over pointer storage.
ruint r_atomic_uint_fetch_or(rauint *a, ruint val)
Atomically compute *a |= val and return the previous *a.
int r_atomic_int_exchange(raint *a, int val)
Atomically write val and return the previous value.
raint raboolean
Atomic-friendly boolean; thin alias over raint so the boolean accessors funnel through r_atomic_int_*...
Definition ratomic.h:96
ruint r_atomic_uint_fetch_add(rauint *a, ruint val)
Atomically compute *a += val and return the previous *a.
rboolean r_atomic_int_cmp_xchg_weak(raint *a, int *old, int val)
Weak compare-and-swap: if *a equals *old, store val and return TRUE; otherwise write the current *a b...
rpointer r_atomic_ptr_fetch_add(raptr *a, rpointer val)
Pointer-arithmetic fetch-add: atomically *a += val and return the previous pointer.
rboolean r_atomic_int_cmp_xchg_strong(raint *a, int *old, int val)
Strong compare-and-swap: as r_atomic_int_cmp_xchg_weak but no spurious failure.
void r_atomic_ptr_store(raptr *a, rpointer val)
Atomically store val into a.
rpointer r_atomic_ptr_fetch_or(raptr *a, rpointer val)
Bitwise |= over pointer storage.
rboolean r_atomic_uint_cmp_xchg_strong(rauint *a, ruint *old, ruint val)
Strong CAS; no spurious failures.
rpointer r_atomic_ptr_exchange(raptr *a, rpointer val)
Atomically write val and return the previous value.
int r_atomic_int_fetch_or(raint *a, int val)
Atomically compute *a |= val and return the previous *a.
ruint r_atomic_uint_load(rauint *a)
Atomically read a's value.
int r_atomic_int_fetch_add(raint *a, int val)
Atomically compute *a += val and return the previous *a.
ruint r_atomic_uint_fetch_xor(rauint *a, ruint val)
Atomically compute *a ^= val and return the previous *a.
rboolean r_atomic_ptr_cmp_xchg_weak(raptr *a, rpointer *old, rpointer val)
Weak CAS on pointer storage; see r_atomic_int_cmp_xchg_weak for semantics.
#define R_API
Public-API decoration: resolves to R_API_EXPORT while building rlib and R_API_IMPORT for consumers.
Definition rmacros.h:115
#define TRUE
Boolean true (!FALSE).
Definition rmacros.h:136
#define FALSE
Boolean false (0).
Definition rmacros.h:132
#define R_BEGIN_DECLS
Open an extern "C" block under C++ (no-op in C).
Definition rmacros.h:196
int rboolean
Boolean type (typedef'd to int).
Definition rtypes.h:59
unsigned int ruint
Unsigned int.
Definition rtypes.h:157
unsigned long ruintptr
Unsigned integer wide enough to hold a pointer (like uintptr_t).
Definition rtypes.h:324
void * rpointer
Generic pointer (alias for void *).
Definition rtypes.h:327
Foundational type aliases used by every rlib header.