1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2010 Rémi Denis-Courmont
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
26 * Atomic operations do not require locking, but they are not very powerful.
30 # if (__STDC_VERSION__ >= 201112L) && defined(__STDC_NO_ATOMICS__)
31 # error Atomic operations required!
33 /*** Native C11 atomics ***/
34 # include <stdatomic.h>
37 /*** Native C++11 atomics ***/
39 using std::atomic_is_lock_free;
40 using std::atomic_init;
41 using std::atomic_store;
42 using std::atomic_store_explicit;
43 using std::atomic_load;
44 using std::atomic_load_explicit;
45 using std::atomic_exchange;
46 using std::atomic_exchange_explicit;
47 using std::atomic_compare_exchange_strong;
48 using std::atomic_compare_exchange_strong_explicit;
49 using std::atomic_compare_exchange_weak;
50 using std::atomic_compare_exchange_weak_explicit;
51 using std::atomic_fetch_add;
52 using std::atomic_fetch_add_explicit;
53 using std::atomic_fetch_sub;
54 using std::atomic_fetch_sub_explicit;
55 using std::atomic_fetch_or;
56 using std::atomic_fetch_or_explicit;
57 using std::atomic_fetch_xor;
58 using std::atomic_fetch_xor_explicit;
59 using std::atomic_fetch_and;
60 using std::atomic_fetch_and_explicit;
61 using std::atomic_thread_fence;
62 using std::atomic_signal_fence;
64 using std::memory_order;
65 using std::memory_order_relaxed;
66 using std::memory_order_consume;
67 using std::memory_order_release;
68 using std::memory_order_acq_rel;
69 using std::memory_order_seq_cst;
71 using std::atomic_flag;
72 typedef std::atomic<bool> atomic_bool;
73 typedef std::atomic<char> atomic_char;
74 typedef std::atomic<signed char> atomic_schar;
75 typedef std::atomic<unsigned char> atomic_uchar;
76 typedef std::atomic<short> atomic_short;
77 typedef std::atomic<unsigned short> atomic_ushort;
78 typedef std::atomic<int> atomic_int;
79 typedef std::atomic<unsigned int> atomic_uint;
80 typedef std::atomic<long> atomic_long;
81 typedef std::atomic<unsigned long> atomic_ulong;
82 typedef std::atomic<long long> atomic_llong;
83 typedef std::atomic<unsigned long long> atomic_ullong;
84 typedef std::atomic<char16_t> atomic_char16_t;
85 typedef std::atomic<char32_t> atomic_char32_t;
86 typedef std::atomic<wchar_t> atomic_wchar_t;
87 typedef std::atomic<int_least8_t> atomic_int_least8_t;
88 typedef std::atomic<uint_least8_t> atomic_uint_least8_t;
89 typedef std::atomic<int_least16_t> atomic_int_least16_t;
90 typedef std::atomic<uint_least16_t> atomic_uint_least16_t;
91 typedef std::atomic<int_least32_t> atomic_int_least32_t;
92 typedef std::atomic<uint_least32_t> atomic_uint_least32_t;
93 typedef std::atomic<int_least64_t> atomic_int_least64_t;
94 typedef std::atomic<uint_least64_t> atomic_uint_least64_t;
95 typedef std::atomic<int_fast8_t> atomic_int_fast8_t;
96 typedef std::atomic<uint_fast8_t> atomic_uint_fast8_t;
97 typedef std::atomic<int_fast16_t> atomic_int_fast16_t;
98 typedef std::atomic<uint_fast16_t> atomic_uint_fast16_t;
99 typedef std::atomic<int_fast32_t> atomic_int_fast32_t;
100 typedef std::atomic<uint_fast32_t> atomic_uint_fast32_t;
101 typedef std::atomic<int_fast64_t> atomic_int_fast64_t;
102 typedef std::atomic<uint_fast64_t> atomic_uint_fast64_t;
103 typedef std::atomic<intptr_t> atomic_intptr_t;
104 typedef std::atomic<uintptr_t> atomic_uintptr_t;
105 typedef std::atomic<size_t> atomic_size_t;
106 typedef std::atomic<ptrdiff_t> atomic_ptrdiff_t;
107 typedef std::atomic<intmax_t> atomic_intmax_t;
108 typedef std::atomic<uintmax_t> atomic_uintmax_t;
112 typedef atomic_uint_least32_t vlc_atomic_float;
114 static inline void vlc_atomic_init_float(vlc_atomic_float *var, float f)
116 union { float f; uint32_t i; } u;
118 atomic_init(var, u.i);
121 /** Helper to retrieve a single precision from an atom. */
122 static inline float vlc_atomic_load_float(vlc_atomic_float *atom)
124 union { float f; uint32_t i; } u;
125 u.i = atomic_load(atom);
129 /** Helper to store a single precision into an atom. */
130 static inline void vlc_atomic_store_float(vlc_atomic_float *atom, float f)
132 union { float f; uint32_t i; } u;
134 atomic_store(atom, u.i);