29#ifndef ETL_ATOMIC_GCC_SYNC_INCLUDED
30#define ETL_ATOMIC_GCC_SYNC_INCLUDED
32#include "../platform.h"
33#include "../type_traits.h"
34#include "../static_assert.h"
35#include "../nullptr.h"
36#include "../char_traits.h"
43#if defined(ETL_COMPILER_ARM5)
44 #define ETL_USE_SYNC_BUILTINS
48#if defined(ETL_COMPILER_ARM6)
49 #if ETL_COMPILER_FULL_VERSION >= 40700
50 #define ETL_USE_ATOMIC_BUILTINS
52 #define ETL_USE_SYNC_BUILTINS
57#if defined(ETL_COMPILER_GCC)
58 #if ETL_COMPILER_FULL_VERSION >= 40700
59 #define ETL_USE_ATOMIC_BUILTINS
61 #define ETL_USE_SYNC_BUILTINS
66#if defined(ETL_COMPILER_CLANG)
67 #if ETL_COMPILER_FULL_VERSION >= 50000
68 #define ETL_USE_ATOMIC_BUILTINS
70 #define ETL_USE_SYNC_BUILTINS
76#if defined(ETL_USE_ATOMIC_BUILTINS)
78#define ETL_BUILTIN_LOCK while (__atomic_test_and_set(&flag, etl::memory_order_seq_cst)) {}
79#define ETL_BUILTIN_UNLOCK __atomic_clear(&flag, etl::memory_order_seq_cst);
88 memory_order_relaxed = __ATOMIC_RELAXED,
89 memory_order_consume = __ATOMIC_CONSUME,
90 memory_order_acquire = __ATOMIC_ACQUIRE,
91 memory_order_release = __ATOMIC_RELEASE,
92 memory_order_acq_rel = __ATOMIC_ACQ_REL,
93 memory_order_seq_cst = __ATOMIC_SEQ_CST
99 template <typename T, bool integral_type = etl::is_integral<T>::value>
122 T operator =(T v)
volatile
132 return __atomic_add_fetch(&value, 1, etl::memory_order_seq_cst);
135 T operator ++()
volatile
137 return __atomic_add_fetch(&value, 1, etl::memory_order_seq_cst);
143 return __atomic_fetch_add(&value, 1, etl::memory_order_seq_cst);
146 T operator ++(
int)
volatile
148 return __atomic_fetch_add(&value, 1, etl::memory_order_seq_cst);
154 return __atomic_sub_fetch(&value, 1, etl::memory_order_seq_cst);
157 T operator --()
volatile
159 return __atomic_sub_fetch(&value, 1, etl::memory_order_seq_cst);
165 return __atomic_fetch_sub(&value, 1, etl::memory_order_seq_cst);
168 T operator --(
int)
volatile
170 return __atomic_fetch_sub(&value, 1, etl::memory_order_seq_cst);
176 return __atomic_fetch_add(&value, v, etl::memory_order_seq_cst);
179 T operator +=(T v)
volatile
181 return __atomic_fetch_add(&value, v, etl::memory_order_seq_cst);
187 return __atomic_fetch_sub(&value, v, etl::memory_order_seq_cst);
190 T operator -=(T v)
volatile
192 return __atomic_fetch_sub(&value, v, etl::memory_order_seq_cst);
198 return __atomic_fetch_and(&value, v, etl::memory_order_seq_cst);
203 return __atomic_fetch_and(&value, v, etl::memory_order_seq_cst);
209 return __atomic_fetch_or(&value, v, etl::memory_order_seq_cst);
214 return __atomic_fetch_or(&value, v, etl::memory_order_seq_cst);
220 return __atomic_fetch_xor(&value, v, etl::memory_order_seq_cst);
225 return __atomic_fetch_xor(&value, v, etl::memory_order_seq_cst);
231 return __atomic_fetch_add(&value, 0, etl::memory_order_seq_cst);
234 operator T()
volatile const
236 return __atomic_fetch_add(&value, 0, etl::memory_order_seq_cst);
240 bool is_lock_free()
const
245 bool is_lock_free()
const volatile
251 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
253 __atomic_store_n(&value, v, order);
256 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
258 __atomic_store_n(&value, v, order);
262 T load(etl::memory_order order = etl::memory_order_seq_cst)
const
264 return __atomic_load_n(&value, order);
267 T load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
269 return __atomic_load_n(&value, order);
273 T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst)
275 return __atomic_fetch_add(&value, v, order);
278 T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
280 return __atomic_fetch_add(&value, v, order);
284 T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst)
286 return __atomic_fetch_sub(&value, v, order);
289 T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
291 return __atomic_fetch_sub(&value, v, order);
295 T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst)
297 return __atomic_fetch_or(&value, v, order);
300 T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
302 return __atomic_fetch_or(&value, v, order);
306 T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst)
308 return __atomic_fetch_and(&value, v, order);
311 T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
313 return __atomic_fetch_and(&value, v, order);
317 T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst)
319 return __atomic_fetch_xor(&value, v, order);
322 T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
324 return __atomic_fetch_xor(&value, v, order);
328 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
330 return __atomic_exchange_n(&value, v, order);
333 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
335 return __atomic_exchange_n(&value, v, order);
339 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
341 return __atomic_compare_exchange_n(&value, &expected, desired,
true, order, order);
344 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
346 return __atomic_compare_exchange_n(&value, &expected, desired,
true, order, order);
349 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
351 return __atomic_compare_exchange_n(&value, &expected, desired,
true, success, failure);
354 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
356 return __atomic_compare_exchange_n(&value, &expected, desired,
true, success, failure);
360 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
362 return __atomic_compare_exchange_n(&value, &expected, desired,
false, order, order);
365 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
367 return __atomic_compare_exchange_n(&value, &expected, desired,
false, order, order);
370 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
372 return __atomic_compare_exchange_n(&value, &expected, desired,
false, success, failure);
375 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
377 return __atomic_compare_exchange_n(&value, &expected, desired,
false, success, failure);
382 atomic& operator =(
const atomic&) ETL_DELETE;
383 atomic& operator =(
const atomic&)
volatile ETL_DELETE;
391 template <
typename T>
392 class atomic<T*,
false>
402 : value(uintptr_t(v))
414 T* operator =(T* v)
volatile
424 return reinterpret_cast<T*
>(__atomic_add_fetch(&value,
sizeof(T), etl::memory_order_seq_cst));
427 T* operator ++()
volatile
429 return reinterpret_cast<T*
>(__atomic_add_fetch(&value,
sizeof(T), etl::memory_order_seq_cst));
435 return reinterpret_cast<T*
>(__atomic_fetch_add(&value,
sizeof(T), etl::memory_order_seq_cst));
438 T* operator ++(
int)
volatile
440 return reinterpret_cast<T*
>(__atomic_fetch_add(&value,
sizeof(T), etl::memory_order_seq_cst));
446 return reinterpret_cast<T*
>(__atomic_sub_fetch(&value,
sizeof(T), etl::memory_order_seq_cst));
449 T* operator --()
volatile
451 return reinterpret_cast<T*
>(__atomic_sub_fetch(&value,
sizeof(T), etl::memory_order_seq_cst));
457 return reinterpret_cast<T*
>(__atomic_fetch_sub(&value,
sizeof(T), etl::memory_order_seq_cst));
460 T* operator --(
int)
volatile
462 return reinterpret_cast<T*
>(__atomic_fetch_sub(&value,
sizeof(T), etl::memory_order_seq_cst));
466 T* operator +=(ptrdiff_t v)
468 return reinterpret_cast<T*
>(__atomic_fetch_add(&value, v *
sizeof(T), etl::memory_order_seq_cst));
471 T* operator +=(ptrdiff_t v)
volatile
473 return reinterpret_cast<T*
>(__atomic_fetch_add(&value, v *
sizeof(T), etl::memory_order_seq_cst));
477 T* operator -=(ptrdiff_t v)
479 return reinterpret_cast<T*
>(__atomic_fetch_sub(&value, v *
sizeof(T), etl::memory_order_seq_cst));
482 T* operator -=(ptrdiff_t v)
volatile
484 return reinterpret_cast<T*
>(__atomic_fetch_sub(&value, v *
sizeof(T), etl::memory_order_seq_cst));
490 return reinterpret_cast<T*
>(__atomic_fetch_add(&value, 0, etl::memory_order_seq_cst));
493 operator T*()
volatile const
495 return reinterpret_cast<T*
>(__atomic_fetch_add(&value, 0, etl::memory_order_seq_cst));
499 bool is_lock_free()
const
504 bool is_lock_free()
const volatile
510 void store(T* v, etl::memory_order order = etl::memory_order_seq_cst)
512 __atomic_store_n(&value, uintptr_t(v), order);
515 void store(T* v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
517 __atomic_store_n(&value, uintptr_t(v), order);
521 T* load(etl::memory_order order = etl::memory_order_seq_cst)
const
523 return reinterpret_cast<T*
>(__atomic_load_n(&value, order));
526 T* load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
528 return reinterpret_cast<T*
>(__atomic_load_n(&value, order));
532 T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
534 return reinterpret_cast<T*
>(__atomic_fetch_add(&value, v, order));
537 T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
539 return reinterpret_cast<T*
>(__atomic_fetch_add(&value, v, order));
543 T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
545 return reinterpret_cast<T*
>(__atomic_fetch_sub(&value, v, order));
548 T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
550 return reinterpret_cast<T*
>(__atomic_fetch_sub(&value, v, order));
554 T*
exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst)
556 return reinterpret_cast<T*
>(__atomic_exchange_n(&value, uintptr_t(v), order));
559 T*
exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
561 return reinterpret_cast<T*
>(__atomic_exchange_n(&value, uintptr_t(v), order));
565 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
567 uintptr_t expected_v = uintptr_t(expected);
569 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
true, order, order);
572 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
574 uintptr_t expected_v = uintptr_t(expected);
576 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
true, order, order);
579 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
581 uintptr_t expected_v = uintptr_t(expected);
583 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
true, success, failure);
586 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
volatile
588 uintptr_t expected_v = uintptr_t(expected);
590 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
true, success, failure);
594 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
596 uintptr_t expected_v = uintptr_t(expected);
598 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
false, order, order);
601 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
603 uintptr_t expected_v = uintptr_t(expected);
605 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
false, order, order);
608 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
610 uintptr_t expected_v = uintptr_t(expected);
612 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
false, success, failure);
615 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
volatile
617 uintptr_t expected_v = uintptr_t(expected);
619 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
false, success, failure);
624 atomic& operator =(
const atomic&) ETL_DELETE;
625 atomic& operator =(
const atomic&)
volatile ETL_DELETE;
627 mutable uintptr_t value;
634 class atomic<bool, true>
649 bool operator =(
bool v)
656 bool operator =(
bool v)
volatile
664 operator bool ()
const
666 return static_cast<bool>(__atomic_fetch_add(&value, 0, etl::memory_order_seq_cst));
669 operator bool()
volatile const
671 return static_cast<bool>(__atomic_fetch_add(&value, 0, etl::memory_order_seq_cst));
675 bool is_lock_free()
const
680 bool is_lock_free()
const volatile
686 void store(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
688 __atomic_store_n(&value,
char(v), order);
691 void store(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
693 __atomic_store_n(&value,
char(v), order);
697 bool load(etl::memory_order order = etl::memory_order_seq_cst)
const
699 return static_cast<bool>(__atomic_load_n(&value, order));
702 bool load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
704 return static_cast<bool>(__atomic_load_n(&value, order));
708 bool exchange(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
710 return static_cast<bool>(__atomic_exchange_n(&value,
char(v), order));
713 bool exchange(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
715 return static_cast<bool>(__atomic_exchange_n(&value,
char(v), order));
719 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
721 char expected_v = char(expected);
722 char desired_v = char(desired);
724 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
true, order, order);
727 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
729 char expected_v = char(expected);
730 char desired_v = char(desired);
732 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
true, order, order);
735 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
737 char expected_v = char(expected);
738 char desired_v = char(desired);
740 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
true, success, failure);
743 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
volatile
745 char expected_v = char(expected);
746 char desired_v = char(desired);
748 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
true, success, failure);
752 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
754 char expected_v = char(expected);
755 char desired_v = char(desired);
757 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
false, order, order);
760 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
762 char expected_v = char(expected);
763 char desired_v = char(desired);
765 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
false, order, order);
768 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
770 char expected_v = char(expected);
771 char desired_v = char(desired);
773 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
false, success, failure);
776 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
volatile
778 char expected_v = char(expected);
779 char desired_v = char(desired);
781 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
false, success, failure);
786 atomic& operator =(
const atomic&) ETL_DELETE;
787 atomic& operator =(
const atomic&)
volatile ETL_DELETE;
796 template <
typename T>
797 class atomic<T, false>
821 T operator =(T v)
volatile
838 operator T()
volatile const
848 bool is_lock_free()
const
853 bool is_lock_free()
const volatile
859 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
867 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
876 T load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
887 T load(etl::memory_order order = etl::memory_order_seq_cst)
const
898 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
909 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
921 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
927 if (memcmp(&value, &expected,
sizeof(T)) == 0)
941 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
947 if (memcmp(&value, &expected,
sizeof(T)) == 0)
961 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
965 return compare_exchange_weak(expected, desired);
968 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
972 return compare_exchange_weak(expected, desired);
976 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
979 return compare_exchange_weak(expected, desired);
982 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
985 return compare_exchange_weak(expected, desired);
988 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
992 return compare_exchange_weak(expected, desired);
995 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
999 return compare_exchange_weak(expected, desired);
1008#undef ETL_BUILTIN_LOCK
1009#undef ETL_BUILTIN_UNLOCK
1013#if defined(ETL_USE_SYNC_BUILTINS)
1015#define ETL_BUILTIN_LOCK while (__sync_lock_test_and_set(&flag, 1U)) {}
1016#define ETL_BUILTIN_UNLOCK __sync_lock_release(&flag);
1023 typedef enum memory_order
1025 memory_order_relaxed,
1026 memory_order_consume,
1027 memory_order_acquire,
1028 memory_order_release,
1029 memory_order_acq_rel,
1030 memory_order_seq_cst
1036 template <typename T, bool integral_type = etl::is_integral<T>::value>
1061 T operator =(T v)
volatile
1071 return __sync_add_and_fetch(&value, 1);
1074 T operator ++()
volatile
1076 return __sync_add_and_fetch(&value, 1);
1082 return __sync_fetch_and_add(&value, 1);
1085 T operator ++(
int)
volatile
1087 return __sync_fetch_and_add(&value, 1);
1093 return __sync_sub_and_fetch(&value, 1);
1096 T operator --()
volatile
1098 return __sync_sub_and_fetch(&value, 1);
1104 return __sync_fetch_and_sub(&value, 1);
1107 T operator --(
int)
volatile
1109 return __sync_fetch_and_sub(&value, 1);
1115 return __sync_fetch_and_add(&value, v);
1118 T operator +=(T v)
volatile
1120 return __sync_fetch_and_add(&value, v);
1126 return __sync_fetch_and_sub(&value, v);
1129 T operator -=(T v)
volatile
1131 return __sync_fetch_and_sub(&value, v);
1137 return __sync_fetch_and_and(&value, v);
1142 return __sync_fetch_and_and(&value, v);
1148 return __sync_fetch_and_or(&value, v);
1153 return __sync_fetch_and_or(&value, v);
1159 return __sync_fetch_and_xor(&value, v);
1164 return __sync_fetch_and_xor(&value, v);
1170 return __sync_fetch_and_add(&value, 0);
1173 operator T()
volatile const
1175 return __sync_fetch_and_add(&value, 0);
1179 bool is_lock_free()
const
1184 bool is_lock_free()
const volatile
1190 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
1193 (void)__sync_lock_test_and_set(&value, v);
1196 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1199 (void)__sync_lock_test_and_set(&value, v);
1203 T load(etl::memory_order order = etl::memory_order_seq_cst)
const
1206 return __sync_fetch_and_add(&value, 0);
1209 T load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
1212 return __sync_fetch_and_add(&value, 0);
1216 T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst)
1219 return __sync_fetch_and_add(&value, v);
1222 T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1225 return __sync_fetch_and_add(&value, v);
1229 T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst)
1232 return __sync_fetch_and_sub(&value, v);
1235 T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1238 return __sync_fetch_and_sub(&value, v);
1242 T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst)
1245 return __sync_fetch_and_or(&value, v);
1248 T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1251 return __sync_fetch_and_or(&value, v);
1255 T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst)
1258 return __sync_fetch_and_and(&value, v);
1261 T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1264 return __sync_fetch_and_and(&value, v);
1268 T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst)
1271 return __sync_fetch_and_xor(&value, v);
1274 T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1277 return __sync_fetch_and_xor(&value, v);
1281 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
1284 return __sync_lock_test_and_set(&value, v);
1287 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1290 return __sync_lock_test_and_set(&value, v);
1294 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
1297 T old = __sync_val_compare_and_swap(&value, expected, desired);
1299 if (old == expected)
1310 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1313 T old = __sync_val_compare_and_swap(&value, expected, desired);
1315 if (old == expected)
1326 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
1330 T old = __sync_val_compare_and_swap(&value, expected, desired);
1332 if (old == expected)
1343 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
1347 T old = __sync_val_compare_and_swap(&value, expected, desired);
1349 if (old == expected)
1361 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
1366 while (!compare_exchange_weak(old, desired))
1368 if (memcmp(&old, &expected,
sizeof(T)))
1378 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1383 while (!compare_exchange_weak(old, desired))
1385 if (memcmp(&old, &expected,
sizeof(T)))
1395 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
1401 while (!compare_exchange_weak(old, desired))
1403 if (memcmp(&old, &expected,
sizeof(T)))
1413 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
1419 while (!compare_exchange_weak(old, desired))
1421 if (memcmp(&old, &expected,
sizeof(T)))
1433 atomic& operator =(
const atomic&) ETL_DELETE;
1434 atomic& operator =(
const atomic&)
volatile ETL_DELETE;
1436 mutable volatile T value;
1442 template <
typename T>
1443 class atomic<T*,
false>
1453 : value(uintptr_t(v))
1465 T* operator =(T* v)
volatile
1475 return reinterpret_cast<T*
>(__sync_add_and_fetch(&value,
sizeof(T)));
1478 T* operator ++()
volatile
1480 return reinterpret_cast<T*
>(__sync_add_and_fetch(&value,
sizeof(T)));
1486 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value,
sizeof(T)));
1489 T* operator ++(
int)
volatile
1491 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value,
sizeof(T)));
1497 return reinterpret_cast<T*
>(__sync_sub_and_fetch(&value,
sizeof(T)));
1500 T* operator --()
volatile
1502 return reinterpret_cast<T*
>(__sync_sub_and_fetch(&value,
sizeof(T)));
1508 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value,
sizeof(T)));
1511 T* operator --(
int)
volatile
1513 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value,
sizeof(T)));
1517 T* operator +=(ptrdiff_t v)
1519 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, v *
sizeof(T)));
1522 T* operator +=(ptrdiff_t v)
volatile
1524 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, v *
sizeof(T)));
1528 T* operator -=(ptrdiff_t v)
1530 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value, v *
sizeof(T)));
1533 T* operator -=(ptrdiff_t v)
volatile
1535 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value, v *
sizeof(T)));
1539 operator T* ()
const
1541 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, 0));
1544 operator T* ()
volatile const
1546 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, 0));
1550 bool is_lock_free()
const
1555 bool is_lock_free()
const volatile
1561 void store(T* v, etl::memory_order order = etl::memory_order_seq_cst)
1563 __sync_lock_test_and_set(&value, uintptr_t(v));
1566 void store(T* v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1568 __sync_lock_test_and_set(&value, uintptr_t(v));
1572 T* load(etl::memory_order order = etl::memory_order_seq_cst)
const
1574 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, 0));
1577 T* load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
1579 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, 0));
1583 T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
1585 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, v));
1588 T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1590 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, v));
1594 T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
1596 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value, v));
1599 T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1601 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value, v));
1605 T*
exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst)
1607 return reinterpret_cast<T*
>(__sync_lock_test_and_set(&value, uintptr_t(v)));
1610 T*
exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1612 return reinterpret_cast<T*
>(__sync_lock_test_and_set(&value, uintptr_t(v)));
1616 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
1618 T* old =
reinterpret_cast<T*
>(__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired)));
1620 if (old == expected)
1631 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1633 T* old =
reinterpret_cast<T*
>(__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired)));
1635 if (old == expected)
1646 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
1648 T* old =
reinterpret_cast<T*
>(__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired)));
1650 if (old == expected)
1661 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
volatile
1663 T* old =
reinterpret_cast<T*
>(__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired)));
1665 if (old == expected)
1677 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
1681 while (!compare_exchange_weak(old, desired))
1683 if (memcmp(&old, &expected,
sizeof(T*)))
1693 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1697 while (!compare_exchange_weak(old, desired))
1699 if (memcmp(&old, &expected,
sizeof(T*)))
1709 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
1713 while (!compare_exchange_weak(old, desired))
1715 if (memcmp(&old, &expected,
sizeof(T*)))
1725 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
volatile
1729 while (!compare_exchange_weak(old, desired))
1731 if (memcmp(&old, &expected,
sizeof(T*)))
1743 atomic& operator =(
const atomic&) ETL_DELETE;
1744 atomic& operator =(
const atomic&)
volatile ETL_DELETE;
1746 mutable uintptr_t value;
1753 class atomic<bool, true>
1768 bool operator =(
bool v)
1775 bool operator =(
bool v)
volatile
1783 operator bool()
const
1785 return static_cast<bool>(__sync_fetch_and_add(&value, 0));
1788 operator bool()
volatile const
1790 return static_cast<bool>(__sync_fetch_and_add(&value, 0));
1794 bool is_lock_free()
const
1799 bool is_lock_free()
const volatile
1805 void store(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
1807 __sync_lock_test_and_set(&value,
char(v));
1810 void store(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1812 __sync_lock_test_and_set(&value,
char(v));
1816 bool load(etl::memory_order order = etl::memory_order_seq_cst)
const
1818 return static_cast<bool>(__sync_fetch_and_add(&value, 0));
1821 bool load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
1823 return static_cast<bool>(__sync_fetch_and_add(&value, 0));
1827 bool exchange(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
1829 return static_cast<bool>(__sync_lock_test_and_set(&value,
char(v)));
1832 bool exchange(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1834 return static_cast<bool>(__sync_lock_test_and_set(&value,
char(v)));
1838 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
1840 bool old =
static_cast<bool>(__sync_val_compare_and_swap(&value,
char(expected),
char(desired)));
1842 if (old == expected)
1853 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1855 bool old =
static_cast<bool>(__sync_val_compare_and_swap(&value,
char(expected),
char(desired)));
1857 if (old == expected)
1868 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
1870 bool old =
static_cast<bool>(__sync_val_compare_and_swap(&value,
char(expected),
char(desired)));
1872 if (old == expected)
1883 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
volatile
1885 bool old =
static_cast<bool>(__sync_val_compare_and_swap(&value,
char(expected),
char(desired)));
1887 if (old == expected)
1899 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
1901 bool old = expected;
1903 while (!compare_exchange_weak(old, desired))
1905 if (memcmp(&old, &expected,
sizeof(
bool)))
1915 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1917 bool old = expected;
1919 while (!compare_exchange_weak(old, desired))
1921 if (memcmp(&old, &expected,
sizeof(
bool)))
1931 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
1933 bool old = expected;
1935 while (!compare_exchange_weak(old, desired))
1937 if (memcmp(&old, &expected,
sizeof(
bool)))
1947 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
volatile
1949 bool old = expected;
1951 while (!compare_exchange_weak(old, desired))
1953 if (memcmp(&old, &expected,
sizeof(
bool)))
1965 atomic& operator =(
const atomic&) ETL_DELETE;
1966 atomic& operator =(
const atomic&)
volatile ETL_DELETE;
1975 template <
typename T>
1976 class atomic<T, false>
2000 T operator =(T v)
volatile
2017 operator T()
volatile const
2027 bool is_lock_free()
const
2032 bool is_lock_free()
const volatile
2038 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
2045 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
2053 T load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
2063 T load(etl::memory_order order = etl::memory_order_seq_cst)
const
2073 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
2083 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
2094 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
2099 if (memcmp(&value, &expected,
sizeof(T)) == 0)
2113 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
2118 if (memcmp(&value, &expected,
sizeof(T)) == 0)
2132 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
2134 return compare_exchange_weak(expected, desired);
2137 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
2139 return compare_exchange_weak(expected, desired);
2143 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
2145 return compare_exchange_weak(expected, desired);
2148 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
2150 return compare_exchange_weak(expected, desired);
2153 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
2155 return compare_exchange_weak(expected, desired);
2158 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
2160 return compare_exchange_weak(expected, desired);
2169#undef ETL_SYNC_BUILTIN_LOCK
2170#undef ETL_SYNC_BUILTIN_UNLOCK
2187#if ETL_HAS_NATIVE_CHAR8_T
2190#if ETL_HAS_NATIVE_CHAR16_T
2193#if ETL_HAS_NATIVE_CHAR32_T
2196#if ETL_USING_8BIT_TYPES
2204#if ETL_USING_64BIT_TYPES
2214#if ETL_USING_64BIT_TYPES
2224#if ETL_USING_64BIT_TYPES
is_integral
Definition type_traits_generator.h:1001
bitset_ext
Definition absolute.h:38
T exchange(T &object, const T &new_value)
exchange (const)
Definition utility.h:454
etl::byte & operator^=(etl::byte &lhs, etl::byte rhs)
Exclusive or equals.
Definition byte.h:305
etl::byte & operator|=(etl::byte &lhs, etl::byte rhs)
Or equals.
Definition byte.h:289
etl::byte & operator&=(etl::byte &lhs, etl::byte rhs)
And equals.
Definition byte.h:297
pair holds two objects of arbitrary type
Definition utility.h:164