mn_atomic_gcc.hpp
Go to the documentation of this file.
1 /*
2 *This file is part of the Mini Thread Library (https://github.com/RoseLeBlood/MiniThread ).
3 *Copyright (c) 2021 Amber-Sophia Schroeck
4 *
5 *The Mini Thread Library is free software; you can redistribute it and/or modify
6 *it under the terms of the GNU Lesser General Public License as published by
7 *the Free Software Foundation, version 3, or (at your option) any later version.
8 
9 *The Mini Thread Library is distributed in the hope that it will be useful, but
10 *WITHOUT ANY WARRANTY; without even the implied warranty of
11 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 *General Public License for more details.
13 *
14 *You should have received a copy of the GNU Lesser General Public
15 *License along with the Mini Thread Library; if not, see
16 *<https://www.gnu.org/licenses/>.
17 */
18 #ifndef _MINLIB_76a34886_76df_4d18_a155_85d3730cbe17_H_
19 #define _MINLIB_76a34886_76df_4d18_a155_85d3730cbe17_H_
20 
21 #include "../mn_def.hpp"
22 
23 #ifdef __GCC_ATOMIC_BOOL_LOCK_FREE
24 #define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
25 #endif
26 #ifdef __GCC_ATOMIC_CHAR_LOCK_FREE
27 #define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
28 #endif
29 #ifdef __GCC_ATOMIC_CHAR16_T_LOCK_FREE
30 #define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
31 #endif
32 #ifdef __GCC_ATOMIC_CHAR32_T_LOCK_FREE
33 #define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
34 #endif
35 #ifdef __GCC_ATOMIC_WCHAR_T_LOCK_FREE
36 #define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
37 #endif
38 #ifdef __GCC_ATOMIC_SHORT_LOCK_FREE
39 #define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
40 #endif
41 #ifdef __GCC_ATOMIC_INT_LOCK_FREE
42 #define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
43 #endif
44 #ifdef __GCC_ATOMIC_LONG_LOCK_FREE
45 #define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
46 #endif
47 #ifdef __GCC_ATOMIC_LLONG_LOCK_FREE
48 #define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
49 #endif
50 #ifdef __GCC_ATOMIC_POINTER_LOCK_FREE
51 #define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
52 #endif
53 
54 namespace mn {
59  template <typename T >
61  static_assert(__is_trivially_copyable(T),"mn::atomic requires a trivially copyable type");
62  static_assert(sizeof(T) > 0, "Incomplete or zero-sized types are not supported");
63 
64  static constexpr bool is_always_lock_free = __atomic_always_lock_free(sizeof(T), 0);
65 
66  using value_type = T;
67  using difference_type = T;
69 
70  basic_atomic_gcc() = default;
71  ~basic_atomic_gcc() = default;
72 
73  basic_atomic_gcc(const self_type&) = delete;
75  basic_atomic_gcc& operator=(const self_type&) volatile = delete;
76 
77  constexpr basic_atomic_gcc(value_type value) : __tValue(value) { }
78 
79  value_type get() { return __tValue; }
80 
82  { __atomic_store_n (&__tValue, v, static_cast<int>(order)); }
83 
85  { return __atomic_load_n (&__tValue, static_cast<int>(order)); }
86 
88  { return __atomic_exchange_n (&__tValue, v, static_cast<int>(order)); }
89 
90  bool compare_exchange_n (value_type& expected, value_type& desired, bool b,
92  { return __atomic_compare_exchange_n (&__tValue, &expected, desired, b,
93  order, static_cast<int>(order)); }
94 
95  bool compare_exchange_t (value_type& expected, value_type& desired,
97  { return compare_exchange_n (&expected, desired, true,
98  static_cast<int>(order)); }
99 
100  bool compare_exchange_f (value_type& expected, value_type& desired,
102  { return compare_exchange_n (&expected, desired, false,
103  static_cast<int>(order)); }
104 
105 
108  { return _atomic_compare_exchange (&__tValue, &expected, &desired, 0,
109  order, static_cast<int>(order)); }
110 
111  bool compare_exchange_weak(value_type& expected, value_type& desired,
113  { return _atomic_compare_exchange (&__tValue, &expected, &desired, 1,
114  order, static_cast<int>(order)); }
115 
117  { return __atomic_fetch_add (&__tValue, v, static_cast<int>(order)); }
118 
120  { return __atomic_fetch_sub (&__tValue, v, static_cast<int>(order)); }
121 
123  { return __atomic_fetch_and (&__tValue, v, static_cast<int>(order)); }
124 
126  { return __atomic_fetch_or (&__tValue, v, static_cast<int>(order)); }
127 
129  { return __atomic_fetch_xor (&__tValue, v, static_cast<int>(order)); }
130 
132  { return __atomic_add_fetch (&__tValue, v, static_cast<int>(order)); }
133 
135  { return __atomic_sub_fetch (&__tValue, v, static_cast<int>(order)); }
136 
138  { return __atomic_and_fetch (&__tValue, v, static_cast<int>(order)); }
139 
141  { return __atomic_or_fetch (&__tValue, v, static_cast<int>(order)); }
142 
144  { return __atomic_xor_fetch (&__tValue, v, static_cast<int>(order)); }
145 
146  bool is_lock_free() const
147  { return __atomic_is_lock_free (sizeof(value_type), &__tValue); }
148 
149  bool is_lock_free() const volatile
150  { return __atomic_is_lock_free (sizeof(value_type), &__tValue); }
151 
152  inline operator value_type() const { return load(); }
153  inline operator value_type() const volatile { return load(); }
154 
155  inline value_type operator ++ (int) { return add_fetch (1); }
156  inline value_type operator -- (int) { return sub_fetch (1); }
157  inline value_type operator ++ () { return add_fetch (1); }
158  inline value_type operator -- () { return sub_fetch (1); }
159 
160  inline value_type operator ++ (int) volatile { return add_fetch (1); }
161  inline value_type operator -- (int) volatile { return sub_fetch (1); }
162  inline value_type operator ++ () volatile { return add_fetch (1); }
163  inline value_type operator -- () volatile { return sub_fetch (1); }
164 
165 
166  inline value_type operator += (value_type v) { return add_fetch (v); }
167  inline value_type operator -= (value_type v) { return sub_fetch (v); }
168  inline value_type operator &= (value_type v) { return and_fetch (v); }
169  inline value_type operator |= (value_type v) { return or_fetch (v); }
170  inline value_type operator ^= (value_type v) { return xor_fetch (v); }
171 
172  inline value_type operator = (value_type v) { store(v); return v; }
173  inline value_type operator = (value_type v) volatile { store(v); return v; }
174 
176  };
177 }
178 
179 #endif
order
Definition: mn_endianness.hpp:28
struct mn::memory::detail::ptr_difference T
Definition: mn_atomic_singleton.hpp:38
Definition: mn_allocator_typetraits.hpp:25
memory_order
Definition: mn_atomic_flags.hpp:41
Generic atomic type, primary class template.
Definition: mn_atomic_gcc.hpp:60
value_type load(memory_order order=memory_order::SeqCst) const
Definition: mn_atomic_gcc.hpp:84
basic_atomic_gcc & operator=(const self_type &) volatile=delete
static constexpr bool is_always_lock_free
Definition: mn_atomic_gcc.hpp:64
void store(value_type v, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:81
bool compare_exchange_f(value_type &expected, value_type &desired, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:100
value_type operator|=(value_type v)
Definition: mn_atomic_gcc.hpp:169
basic_atomic_gcc()=default
value_type sub_fetch(value_type v, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:134
value_type exchange(value_type v, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:87
value_type fetch_sub(value_type v, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:119
bool compare_exchange_strong(value_type &expected, value_type &desired, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:106
value_type operator&=(value_type v)
Definition: mn_atomic_gcc.hpp:168
value_type fetch_xor(value_type v, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:128
value_type operator-=(value_type v)
Definition: mn_atomic_gcc.hpp:167
bool is_lock_free() const volatile
Definition: mn_atomic_gcc.hpp:149
value_type operator+=(value_type v)
Definition: mn_atomic_gcc.hpp:166
value_type fetch_or(value_type v, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:125
bool compare_exchange_t(value_type &expected, value_type &desired, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:95
value_type operator--()
Definition: mn_atomic_gcc.hpp:158
value_type operator^=(value_type v)
Definition: mn_atomic_gcc.hpp:170
basic_atomic_gcc & operator=(const self_type &)=delete
value_type get()
Definition: mn_atomic_gcc.hpp:79
bool compare_exchange_n(value_type &expected, value_type &desired, bool b, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:90
~basic_atomic_gcc()=default
volatile value_type __tValue
Definition: mn_atomic_gcc.hpp:175
value_type fetch_and(value_type v, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:122
T value_type
Definition: mn_atomic_gcc.hpp:66
T difference_type
Definition: mn_atomic_gcc.hpp:67
bool is_lock_free() const
Definition: mn_atomic_gcc.hpp:146
basic_atomic_gcc(const self_type &)=delete
value_type xor_fetch(value_type v, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:143
value_type and_fetch(value_type v, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:137
value_type or_fetch(value_type v, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:140
value_type operator++()
Definition: mn_atomic_gcc.hpp:157
value_type fetch_add(value_type v, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:116
value_type add_fetch(value_type v, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:131
constexpr basic_atomic_gcc(value_type value)
Definition: mn_atomic_gcc.hpp:77
bool compare_exchange_weak(value_type &expected, value_type &desired, memory_order order=memory_order::SeqCst)
Definition: mn_atomic_gcc.hpp:111