xref: /netbsd-src/external/mpl/bind/dist/lib/isc/include/isc/atomic.h (revision bcda20f65a8566e103791ec395f7f499ef322704)
1 /*	$NetBSD: atomic.h,v 1.8 2025/01/26 16:25:40 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * SPDX-License-Identifier: MPL-2.0
7  *
8  * This Source Code Form is subject to the terms of the Mozilla Public
9  * License, v. 2.0. If a copy of the MPL was not distributed with this
10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11  *
12  * See the COPYRIGHT file distributed with this work for additional
13  * information regarding copyright ownership.
14  */
15 
16 #pragma once
17 
18 #include <stdatomic.h>
19 #ifdef __lint__
20 # include <isc/lint-atomic.h>
21 #endif
22 
23 #include <isc/util.h>
24 
25 /*
26  * We define a few additional macros to make things easier
27  */
28 
29 /* Relaxed Memory Ordering */
30 
31 #define atomic_store_relaxed(o, v) \
32 	atomic_store_explicit((o), (v), memory_order_relaxed)
33 #define atomic_load_relaxed(o) atomic_load_explicit((o), memory_order_relaxed)
34 #define atomic_fetch_add_relaxed(o, v) \
35 	atomic_fetch_add_explicit((o), (v), memory_order_relaxed)
36 #define atomic_fetch_sub_relaxed(o, v) \
37 	atomic_fetch_sub_explicit((o), (v), memory_order_relaxed)
38 #define atomic_fetch_or_relaxed(o, v) \
39 	atomic_fetch_or_explicit((o), (v), memory_order_relaxed)
40 #define atomic_fetch_and_relaxed(o, v) \
41 	atomic_fetch_and_explicit((o), (v), memory_order_relaxed)
42 #define atomic_exchange_relaxed(o, v) \
43 	atomic_exchange_explicit((o), (v), memory_order_relaxed)
44 #define atomic_compare_exchange_weak_relaxed(o, e, d) \
45 	atomic_compare_exchange_weak_explicit(        \
46 		(o), (e), (d), memory_order_relaxed, memory_order_relaxed)
47 #define atomic_compare_exchange_strong_relaxed(o, e, d) \
48 	atomic_compare_exchange_strong_explicit(        \
49 		(o), (e), (d), memory_order_relaxed, memory_order_relaxed)
50 
51 /* Acquire-Release Memory Ordering */
52 
53 #define atomic_store_release(o, v) \
54 	atomic_store_explicit((o), (v), memory_order_release)
55 #define atomic_load_acquire(o) atomic_load_explicit((o), memory_order_acquire)
56 #define atomic_fetch_add_release(o, v) \
57 	atomic_fetch_add_explicit((o), (v), memory_order_release)
58 #define atomic_fetch_sub_release(o, v) \
59 	atomic_fetch_sub_explicit((o), (v), memory_order_release)
60 #define atomic_fetch_and_release(o, v) \
61 	atomic_fetch_and_explicit((o), (v), memory_order_release)
62 #define atomic_fetch_or_release(o, v) \
63 	atomic_fetch_or_explicit((o), (v), memory_order_release)
64 #define atomic_exchange_acquire(o, v) \
65 	atomic_exchange_explicit((o), (v), memory_order_acquire)
66 #define atomic_exchange_acq_rel(o, v) \
67 	atomic_exchange_explicit((o), (v), memory_order_acq_rel)
68 #define atomic_fetch_sub_acq_rel(o, v) \
69 	atomic_fetch_sub_explicit((o), (v), memory_order_acq_rel)
70 #define atomic_compare_exchange_weak_acq_rel(o, e, d) \
71 	atomic_compare_exchange_weak_explicit(        \
72 		(o), (e), (d), memory_order_acq_rel, memory_order_acquire)
73 #define atomic_compare_exchange_strong_acq_rel(o, e, d) \
74 	atomic_compare_exchange_strong_explicit(        \
75 		(o), (e), (d), memory_order_acq_rel, memory_order_acquire)
76 
77 /* compare/exchange that MUST succeed */
78 #define atomic_compare_exchange_enforced(o, e, d) \
79 	RUNTIME_CHECK(atomic_compare_exchange_strong((o), (e), (d)))
80 
81 /* more comfortable atomic pointer declarations */
82 #define atomic_ptr(type) _Atomic(type *)
83