1 /*-
2  * Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org>
3  *                    David Chisnall <theraven@FreeBSD.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  */
29 
30 #ifndef _STDATOMIC_H_
31 #define	_STDATOMIC_H_
32 
33 #include <sys/cdefs.h>
34 
35 #if defined(__cplusplus) && __cplusplus >= 201103L && __has_include(<atomic>)
36 # if __has_feature(cxx_atomic)
37 #  define _STDATOMIC_HAVE_ATOMIC
38 # endif
39 #endif
40 
41 #ifdef _STDATOMIC_HAVE_ATOMIC
42 
43 /* We have a usable C++ <atomic>; use it instead.  */
44 
45 #include <atomic>
46 
47 #undef _Atomic
48         /* Also defined by <atomic> for gcc.  But not used in macros. */
49         /* Also a clang intrinsic.                                    */
50         /* Should not be used by client code before this file is      */
51         /* included.  The definitions in <atomic> themselves see      */
52         /* the old definition, as they should.                        */
53         /* Client code sees the following definition.                 */
54 
55 #define _Atomic(t) std::atomic<t>
56 
57 using std::atomic_is_lock_free;
58 using std::atomic_init;
59 using std::atomic_store;
60 using std::atomic_store_explicit;
61 using std::atomic_load;
62 using std::atomic_load_explicit;
63 using std::atomic_exchange;
64 using std::atomic_exchange_explicit;
65 using std::atomic_compare_exchange_strong;
66 using std::atomic_compare_exchange_strong_explicit;
67 using std::atomic_compare_exchange_weak;
68 using std::atomic_compare_exchange_weak_explicit;
69 using std::atomic_fetch_add;
70 using std::atomic_fetch_add_explicit;
71 using std::atomic_fetch_sub;
72 using std::atomic_fetch_sub_explicit;
73 using std::atomic_fetch_or;
74 using std::atomic_fetch_or_explicit;
75 using std::atomic_fetch_xor;
76 using std::atomic_fetch_xor_explicit;
77 using std::atomic_fetch_and;
78 using std::atomic_fetch_and_explicit;
79 using std::atomic_thread_fence;
80 using std::atomic_signal_fence;
81 
82 using std::memory_order;
83 using std::memory_order_relaxed;
84 using std::memory_order_consume;
85 using std::memory_order_acquire;
86 using std::memory_order_release;
87 using std::memory_order_acq_rel;
88 using std::memory_order_seq_cst;
89 
90 using std::atomic_bool;
91 using std::atomic_char;
92 using std::atomic_schar;
93 using std::atomic_uchar;
94 using std::atomic_short;
95 using std::atomic_ushort;
96 using std::atomic_int;
97 using std::atomic_uint;
98 using std::atomic_long;
99 using std::atomic_ulong;
100 using std::atomic_llong;
101 using std::atomic_ullong;
102 using std::atomic_char16_t;
103 using std::atomic_char32_t;
104 using std::atomic_wchar_t;
105 using std::atomic_int_least8_t;
106 using std::atomic_uint_least8_t;
107 using std::atomic_int_least16_t;
108 using std::atomic_uint_least16_t;
109 using std::atomic_int_least32_t;
110 using std::atomic_uint_least32_t;
111 using std::atomic_int_least64_t;
112 using std::atomic_uint_least64_t;
113 using std::atomic_int_fast8_t;
114 using std::atomic_uint_fast8_t;
115 using std::atomic_int_fast16_t;
116 using std::atomic_uint_fast16_t;
117 using std::atomic_int_fast32_t;
118 using std::atomic_uint_fast32_t;
119 using std::atomic_int_fast64_t;
120 using std::atomic_uint_fast64_t;
121 using std::atomic_intptr_t;
122 using std::atomic_uintptr_t;
123 using std::atomic_size_t;
124 using std::atomic_ptrdiff_t;
125 using std::atomic_intmax_t;
126 using std::atomic_uintmax_t;
127 
128 #else /* <atomic> unavailable, possibly because this is C, not C++ */
129 
130 /* Actual implementation is in bits/stdatomic.h since our test code is C++. */
131 #include <bits/stdatomic.h>
132 
133 #endif /* <atomic> unavailable */
134 
135 #endif /* !_STDATOMIC_H_ */
136