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);
86 typedef enum memory_order
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
96 template <
bool Is_Always_Lock_Free>
102 template <
bool Is_Always_Lock_Free>
103 ETL_CONSTANT
bool atomic_traits<Is_Always_Lock_Free>::is_always_lock_free;
108 template <typename T, bool integral_type = etl::is_integral<T>::value>
109 class atomic :
public atomic_traits<integral_type>
131 T operator =(T v)
volatile
141 return __atomic_add_fetch(&value, 1, etl::memory_order_seq_cst);
144 T operator ++()
volatile
146 return __atomic_add_fetch(&value, 1, etl::memory_order_seq_cst);
152 return __atomic_fetch_add(&value, 1, etl::memory_order_seq_cst);
155 T operator ++(
int)
volatile
157 return __atomic_fetch_add(&value, 1, etl::memory_order_seq_cst);
163 return __atomic_sub_fetch(&value, 1, etl::memory_order_seq_cst);
166 T operator --()
volatile
168 return __atomic_sub_fetch(&value, 1, etl::memory_order_seq_cst);
174 return __atomic_fetch_sub(&value, 1, etl::memory_order_seq_cst);
177 T operator --(
int)
volatile
179 return __atomic_fetch_sub(&value, 1, etl::memory_order_seq_cst);
185 return __atomic_fetch_add(&value, v, etl::memory_order_seq_cst);
188 T operator +=(T v)
volatile
190 return __atomic_fetch_add(&value, v, etl::memory_order_seq_cst);
196 return __atomic_fetch_sub(&value, v, etl::memory_order_seq_cst);
199 T operator -=(T v)
volatile
201 return __atomic_fetch_sub(&value, v, etl::memory_order_seq_cst);
207 return __atomic_fetch_and(&value, v, etl::memory_order_seq_cst);
212 return __atomic_fetch_and(&value, v, etl::memory_order_seq_cst);
218 return __atomic_fetch_or(&value, v, etl::memory_order_seq_cst);
223 return __atomic_fetch_or(&value, v, etl::memory_order_seq_cst);
229 return __atomic_fetch_xor(&value, v, etl::memory_order_seq_cst);
234 return __atomic_fetch_xor(&value, v, etl::memory_order_seq_cst);
240 return __atomic_fetch_add(&value, 0, etl::memory_order_seq_cst);
243 operator T()
volatile const
245 return __atomic_fetch_add(&value, 0, etl::memory_order_seq_cst);
249 bool is_lock_free()
const
254 bool is_lock_free()
const volatile
260 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
262 __atomic_store_n(&value, v, order);
265 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
267 __atomic_store_n(&value, v, order);
271 T load(etl::memory_order order = etl::memory_order_seq_cst)
const
273 return __atomic_load_n(&value, order);
276 T load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
278 return __atomic_load_n(&value, order);
282 T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst)
284 return __atomic_fetch_add(&value, v, order);
287 T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
289 return __atomic_fetch_add(&value, v, order);
293 T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst)
295 return __atomic_fetch_sub(&value, v, order);
298 T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
300 return __atomic_fetch_sub(&value, v, order);
304 T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst)
306 return __atomic_fetch_or(&value, v, order);
309 T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
311 return __atomic_fetch_or(&value, v, order);
315 T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst)
317 return __atomic_fetch_and(&value, v, order);
320 T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
322 return __atomic_fetch_and(&value, v, order);
326 T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst)
328 return __atomic_fetch_xor(&value, v, order);
331 T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
333 return __atomic_fetch_xor(&value, v, order);
337 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
339 return __atomic_exchange_n(&value, v, order);
342 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
344 return __atomic_exchange_n(&value, v, order);
348 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
350 return __atomic_compare_exchange_n(&value, &expected, desired,
true, order, order);
353 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
355 return __atomic_compare_exchange_n(&value, &expected, desired,
true, order, order);
358 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
360 return __atomic_compare_exchange_n(&value, &expected, desired,
true, success, failure);
363 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
365 return __atomic_compare_exchange_n(&value, &expected, desired,
true, success, failure);
369 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
371 return __atomic_compare_exchange_n(&value, &expected, desired,
false, order, order);
374 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
376 return __atomic_compare_exchange_n(&value, &expected, desired,
false, order, order);
379 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
381 return __atomic_compare_exchange_n(&value, &expected, desired,
false, success, failure);
384 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
386 return __atomic_compare_exchange_n(&value, &expected, desired,
false, success, failure);
391 atomic& operator =(
const atomic&) ETL_DELETE;
392 atomic& operator =(
const atomic&)
volatile ETL_DELETE;
400 template <
typename T>
401 class atomic<T*,
false> :
public atomic_traits<true>
411 : value(uintptr_t(v))
423 T* operator =(T* v)
volatile
433 return reinterpret_cast<T*
>(__atomic_add_fetch(&value,
sizeof(T), etl::memory_order_seq_cst));
436 T* operator ++()
volatile
438 return reinterpret_cast<T*
>(__atomic_add_fetch(&value,
sizeof(T), etl::memory_order_seq_cst));
444 return reinterpret_cast<T*
>(__atomic_fetch_add(&value,
sizeof(T), etl::memory_order_seq_cst));
447 T* operator ++(
int)
volatile
449 return reinterpret_cast<T*
>(__atomic_fetch_add(&value,
sizeof(T), etl::memory_order_seq_cst));
455 return reinterpret_cast<T*
>(__atomic_sub_fetch(&value,
sizeof(T), etl::memory_order_seq_cst));
458 T* operator --()
volatile
460 return reinterpret_cast<T*
>(__atomic_sub_fetch(&value,
sizeof(T), etl::memory_order_seq_cst));
466 return reinterpret_cast<T*
>(__atomic_fetch_sub(&value,
sizeof(T), etl::memory_order_seq_cst));
469 T* operator --(
int)
volatile
471 return reinterpret_cast<T*
>(__atomic_fetch_sub(&value,
sizeof(T), etl::memory_order_seq_cst));
475 T* operator +=(ptrdiff_t v)
477 return reinterpret_cast<T*
>(__atomic_fetch_add(&value, v *
sizeof(T), etl::memory_order_seq_cst));
480 T* operator +=(ptrdiff_t v)
volatile
482 return reinterpret_cast<T*
>(__atomic_fetch_add(&value, v *
sizeof(T), etl::memory_order_seq_cst));
486 T* operator -=(ptrdiff_t v)
488 return reinterpret_cast<T*
>(__atomic_fetch_sub(&value, v *
sizeof(T), etl::memory_order_seq_cst));
491 T* operator -=(ptrdiff_t v)
volatile
493 return reinterpret_cast<T*
>(__atomic_fetch_sub(&value, v *
sizeof(T), etl::memory_order_seq_cst));
499 return reinterpret_cast<T*
>(__atomic_fetch_add(&value, 0, etl::memory_order_seq_cst));
502 operator T*()
volatile const
504 return reinterpret_cast<T*
>(__atomic_fetch_add(&value, 0, etl::memory_order_seq_cst));
508 bool is_lock_free()
const
513 bool is_lock_free()
const volatile
519 void store(T* v, etl::memory_order order = etl::memory_order_seq_cst)
521 __atomic_store_n(&value, uintptr_t(v), order);
524 void store(T* v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
526 __atomic_store_n(&value, uintptr_t(v), order);
530 T* load(etl::memory_order order = etl::memory_order_seq_cst)
const
532 return reinterpret_cast<T*
>(__atomic_load_n(&value, order));
535 T* load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
537 return reinterpret_cast<T*
>(__atomic_load_n(&value, order));
541 T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
543 return reinterpret_cast<T*
>(__atomic_fetch_add(&value, v, order));
546 T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
548 return reinterpret_cast<T*
>(__atomic_fetch_add(&value, v, order));
552 T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
554 return reinterpret_cast<T*
>(__atomic_fetch_sub(&value, v, order));
557 T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
559 return reinterpret_cast<T*
>(__atomic_fetch_sub(&value, v, order));
563 T*
exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst)
565 return reinterpret_cast<T*
>(__atomic_exchange_n(&value, uintptr_t(v), order));
568 T*
exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
570 return reinterpret_cast<T*
>(__atomic_exchange_n(&value, uintptr_t(v), order));
574 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
576 uintptr_t expected_v = uintptr_t(expected);
578 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
true, order, order);
581 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
583 uintptr_t expected_v = uintptr_t(expected);
585 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
true, order, order);
588 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
590 uintptr_t expected_v = uintptr_t(expected);
592 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
true, success, failure);
595 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
volatile
597 uintptr_t expected_v = uintptr_t(expected);
599 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
true, success, failure);
603 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
605 uintptr_t expected_v = uintptr_t(expected);
607 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
false, order, order);
610 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
612 uintptr_t expected_v = uintptr_t(expected);
614 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
false, order, order);
617 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
619 uintptr_t expected_v = uintptr_t(expected);
621 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
false, success, failure);
624 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
volatile
626 uintptr_t expected_v = uintptr_t(expected);
628 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
false, success, failure);
633 atomic& operator =(
const atomic&) ETL_DELETE;
634 atomic& operator =(
const atomic&)
volatile ETL_DELETE;
636 mutable uintptr_t value;
643 class atomic<bool, true> :
public atomic_traits<true>
658 bool operator =(
bool v)
665 bool operator =(
bool v)
volatile
673 operator bool ()
const
675 return static_cast<bool>(__atomic_fetch_add(&value, 0, etl::memory_order_seq_cst));
678 operator bool()
volatile const
680 return static_cast<bool>(__atomic_fetch_add(&value, 0, etl::memory_order_seq_cst));
684 bool is_lock_free()
const
689 bool is_lock_free()
const volatile
695 void store(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
697 __atomic_store_n(&value,
char(v), order);
700 void store(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
702 __atomic_store_n(&value,
char(v), order);
706 bool load(etl::memory_order order = etl::memory_order_seq_cst)
const
708 return static_cast<bool>(__atomic_load_n(&value, order));
711 bool load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
713 return static_cast<bool>(__atomic_load_n(&value, order));
717 bool exchange(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
719 return static_cast<bool>(__atomic_exchange_n(&value,
char(v), order));
722 bool exchange(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
724 return static_cast<bool>(__atomic_exchange_n(&value,
char(v), order));
728 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
730 char expected_v = char(expected);
731 char desired_v = char(desired);
733 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
true, order, order);
736 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
738 char expected_v = char(expected);
739 char desired_v = char(desired);
741 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
true, order, order);
744 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
746 char expected_v = char(expected);
747 char desired_v = char(desired);
749 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
true, success, failure);
752 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
volatile
754 char expected_v = char(expected);
755 char desired_v = char(desired);
757 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
true, success, failure);
761 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
763 char expected_v = char(expected);
764 char desired_v = char(desired);
766 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
false, order, order);
769 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
771 char expected_v = char(expected);
772 char desired_v = char(desired);
774 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
false, order, order);
777 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
779 char expected_v = char(expected);
780 char desired_v = char(desired);
782 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
false, success, failure);
785 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
volatile
787 char expected_v = char(expected);
788 char desired_v = char(desired);
790 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
false, success, failure);
795 atomic& operator =(
const atomic&) ETL_DELETE;
796 atomic& operator =(
const atomic&)
volatile ETL_DELETE;
805 template <
typename T>
806 class atomic<T, false> :
public atomic_traits<false>
830 T operator =(T v)
volatile
847 operator T()
volatile const
857 bool is_lock_free()
const
862 bool is_lock_free()
const volatile
868 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
876 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
885 T load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
896 T load(etl::memory_order order = etl::memory_order_seq_cst)
const
907 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
918 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
930 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
936 if (memcmp(&value, &expected,
sizeof(T)) == 0)
950 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
956 if (memcmp(&value, &expected,
sizeof(T)) == 0)
970 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
974 return compare_exchange_weak(expected, desired);
977 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
981 return compare_exchange_weak(expected, desired);
985 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
988 return compare_exchange_weak(expected, desired);
991 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
994 return compare_exchange_weak(expected, desired);
997 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
1001 return compare_exchange_weak(expected, desired);
1004 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
1008 return compare_exchange_weak(expected, desired);
1017#undef ETL_BUILTIN_LOCK
1018#undef ETL_BUILTIN_UNLOCK
1022#if defined(ETL_USE_SYNC_BUILTINS)
1024#define ETL_BUILTIN_LOCK while (__sync_lock_test_and_set(&flag, 1U)) {}
1025#define ETL_BUILTIN_UNLOCK __sync_lock_release(&flag);
1032 typedef enum memory_order
1034 memory_order_relaxed,
1035 memory_order_consume,
1036 memory_order_acquire,
1037 memory_order_release,
1038 memory_order_acq_rel,
1039 memory_order_seq_cst
1042 template <
bool Is_Always_Lock_Free>
1043 struct atomic_traits
1048 template <
bool Is_Always_Lock_Free>
1049 ETL_CONSTANT
bool atomic_traits<Is_Always_Lock_Free>::is_always_lock_free;
1054 template <typename T, bool integral_type = etl::is_integral<T>::value>
1055 class atomic :
public atomic_traits<integral_type>
1079 T operator =(T v)
volatile
1089 return __sync_add_and_fetch(&value, 1);
1092 T operator ++()
volatile
1094 return __sync_add_and_fetch(&value, 1);
1100 return __sync_fetch_and_add(&value, 1);
1103 T operator ++(
int)
volatile
1105 return __sync_fetch_and_add(&value, 1);
1111 return __sync_sub_and_fetch(&value, 1);
1114 T operator --()
volatile
1116 return __sync_sub_and_fetch(&value, 1);
1122 return __sync_fetch_and_sub(&value, 1);
1125 T operator --(
int)
volatile
1127 return __sync_fetch_and_sub(&value, 1);
1133 return __sync_fetch_and_add(&value, v);
1136 T operator +=(T v)
volatile
1138 return __sync_fetch_and_add(&value, v);
1144 return __sync_fetch_and_sub(&value, v);
1147 T operator -=(T v)
volatile
1149 return __sync_fetch_and_sub(&value, v);
1155 return __sync_fetch_and_and(&value, v);
1160 return __sync_fetch_and_and(&value, v);
1166 return __sync_fetch_and_or(&value, v);
1171 return __sync_fetch_and_or(&value, v);
1177 return __sync_fetch_and_xor(&value, v);
1182 return __sync_fetch_and_xor(&value, v);
1188 return __sync_fetch_and_add(&value, 0);
1191 operator T()
volatile const
1193 return __sync_fetch_and_add(&value, 0);
1197 bool is_lock_free()
const
1202 bool is_lock_free()
const volatile
1208 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
1211 (void)__sync_lock_test_and_set(&value, v);
1214 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1217 (void)__sync_lock_test_and_set(&value, v);
1221 T load(etl::memory_order order = etl::memory_order_seq_cst)
const
1224 return __sync_fetch_and_add(&value, 0);
1227 T load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
1230 return __sync_fetch_and_add(&value, 0);
1234 T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst)
1237 return __sync_fetch_and_add(&value, v);
1240 T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1243 return __sync_fetch_and_add(&value, v);
1247 T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst)
1250 return __sync_fetch_and_sub(&value, v);
1253 T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1256 return __sync_fetch_and_sub(&value, v);
1260 T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst)
1263 return __sync_fetch_and_or(&value, v);
1266 T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1269 return __sync_fetch_and_or(&value, v);
1273 T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst)
1276 return __sync_fetch_and_and(&value, v);
1279 T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1282 return __sync_fetch_and_and(&value, v);
1286 T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst)
1289 return __sync_fetch_and_xor(&value, v);
1292 T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1295 return __sync_fetch_and_xor(&value, v);
1299 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
1302 return __sync_lock_test_and_set(&value, v);
1305 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1308 return __sync_lock_test_and_set(&value, v);
1312 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
1315 T old = __sync_val_compare_and_swap(&value, expected, desired);
1317 if (old == expected)
1328 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1331 T old = __sync_val_compare_and_swap(&value, expected, desired);
1333 if (old == expected)
1344 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
1348 T old = __sync_val_compare_and_swap(&value, expected, desired);
1350 if (old == expected)
1361 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
1365 T old = __sync_val_compare_and_swap(&value, expected, desired);
1367 if (old == expected)
1379 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
1384 while (!compare_exchange_weak(old, desired))
1386 if (memcmp(&old, &expected,
sizeof(T)))
1396 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
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)
1419 while (!compare_exchange_weak(old, desired))
1421 if (memcmp(&old, &expected,
sizeof(T)))
1431 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
1437 while (!compare_exchange_weak(old, desired))
1439 if (memcmp(&old, &expected,
sizeof(T)))
1451 atomic& operator =(
const atomic&) ETL_DELETE;
1452 atomic& operator =(
const atomic&)
volatile ETL_DELETE;
1454 mutable volatile T value;
1460 template <
typename T>
1461 class atomic<T*,
false> :
public atomic_traits<true>
1471 : value(uintptr_t(v))
1483 T* operator =(T* v)
volatile
1493 return reinterpret_cast<T*
>(__sync_add_and_fetch(&value,
sizeof(T)));
1496 T* operator ++()
volatile
1498 return reinterpret_cast<T*
>(__sync_add_and_fetch(&value,
sizeof(T)));
1504 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value,
sizeof(T)));
1507 T* operator ++(
int)
volatile
1509 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value,
sizeof(T)));
1515 return reinterpret_cast<T*
>(__sync_sub_and_fetch(&value,
sizeof(T)));
1518 T* operator --()
volatile
1520 return reinterpret_cast<T*
>(__sync_sub_and_fetch(&value,
sizeof(T)));
1526 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value,
sizeof(T)));
1529 T* operator --(
int)
volatile
1531 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value,
sizeof(T)));
1535 T* operator +=(ptrdiff_t v)
1537 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, v *
sizeof(T)));
1540 T* operator +=(ptrdiff_t v)
volatile
1542 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, v *
sizeof(T)));
1546 T* operator -=(ptrdiff_t v)
1548 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value, v *
sizeof(T)));
1551 T* operator -=(ptrdiff_t v)
volatile
1553 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value, v *
sizeof(T)));
1557 operator T* ()
const
1559 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, 0));
1562 operator T* ()
volatile const
1564 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, 0));
1568 bool is_lock_free()
const
1573 bool is_lock_free()
const volatile
1579 void store(T* v, etl::memory_order order = etl::memory_order_seq_cst)
1581 __sync_lock_test_and_set(&value, uintptr_t(v));
1584 void store(T* v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1586 __sync_lock_test_and_set(&value, uintptr_t(v));
1590 T* load(etl::memory_order order = etl::memory_order_seq_cst)
const
1592 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, 0));
1595 T* load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
1597 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, 0));
1601 T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
1603 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, v));
1606 T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1608 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, v));
1612 T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
1614 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value, v));
1617 T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1619 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value, v));
1623 T*
exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst)
1625 return reinterpret_cast<T*
>(__sync_lock_test_and_set(&value, uintptr_t(v)));
1628 T*
exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1630 return reinterpret_cast<T*
>(__sync_lock_test_and_set(&value, uintptr_t(v)));
1634 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
1636 T* old =
reinterpret_cast<T*
>(__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired)));
1638 if (old == expected)
1649 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1651 T* old =
reinterpret_cast<T*
>(__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired)));
1653 if (old == expected)
1664 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
1666 T* old =
reinterpret_cast<T*
>(__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired)));
1668 if (old == expected)
1679 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
volatile
1681 T* old =
reinterpret_cast<T*
>(__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired)));
1683 if (old == expected)
1695 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
1699 while (!compare_exchange_weak(old, desired))
1701 if (memcmp(&old, &expected,
sizeof(T*)))
1711 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1715 while (!compare_exchange_weak(old, desired))
1717 if (memcmp(&old, &expected,
sizeof(T*)))
1727 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
1731 while (!compare_exchange_weak(old, desired))
1733 if (memcmp(&old, &expected,
sizeof(T*)))
1743 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
volatile
1747 while (!compare_exchange_weak(old, desired))
1749 if (memcmp(&old, &expected,
sizeof(T*)))
1761 atomic& operator =(
const atomic&) ETL_DELETE;
1762 atomic& operator =(
const atomic&)
volatile ETL_DELETE;
1764 mutable uintptr_t value;
1771 class atomic<bool, true> :
public atomic_traits<true>
1786 bool operator =(
bool v)
1793 bool operator =(
bool v)
volatile
1801 operator bool()
const
1803 return static_cast<bool>(__sync_fetch_and_add(&value, 0));
1806 operator bool()
volatile const
1808 return static_cast<bool>(__sync_fetch_and_add(&value, 0));
1812 bool is_lock_free()
const
1817 bool is_lock_free()
const volatile
1823 void store(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
1825 __sync_lock_test_and_set(&value,
char(v));
1828 void store(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1830 __sync_lock_test_and_set(&value,
char(v));
1834 bool load(etl::memory_order order = etl::memory_order_seq_cst)
const
1836 return static_cast<bool>(__sync_fetch_and_add(&value, 0));
1839 bool load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
1841 return static_cast<bool>(__sync_fetch_and_add(&value, 0));
1845 bool exchange(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
1847 return static_cast<bool>(__sync_lock_test_and_set(&value,
char(v)));
1850 bool exchange(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1852 return static_cast<bool>(__sync_lock_test_and_set(&value,
char(v)));
1856 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
1858 bool old =
static_cast<bool>(__sync_val_compare_and_swap(&value,
char(expected),
char(desired)));
1860 if (old == expected)
1871 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1873 bool old =
static_cast<bool>(__sync_val_compare_and_swap(&value,
char(expected),
char(desired)));
1875 if (old == expected)
1886 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
1888 bool old =
static_cast<bool>(__sync_val_compare_and_swap(&value,
char(expected),
char(desired)));
1890 if (old == expected)
1901 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
volatile
1903 bool old =
static_cast<bool>(__sync_val_compare_and_swap(&value,
char(expected),
char(desired)));
1905 if (old == expected)
1917 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
1919 bool old = expected;
1921 while (!compare_exchange_weak(old, desired))
1923 if (memcmp(&old, &expected,
sizeof(
bool)))
1933 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1935 bool old = expected;
1937 while (!compare_exchange_weak(old, desired))
1939 if (memcmp(&old, &expected,
sizeof(
bool)))
1949 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
1951 bool old = expected;
1953 while (!compare_exchange_weak(old, desired))
1955 if (memcmp(&old, &expected,
sizeof(
bool)))
1965 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
volatile
1967 bool old = expected;
1969 while (!compare_exchange_weak(old, desired))
1971 if (memcmp(&old, &expected,
sizeof(
bool)))
1983 atomic& operator =(
const atomic&) ETL_DELETE;
1984 atomic& operator =(
const atomic&)
volatile ETL_DELETE;
1993 template <
typename T>
1994 class atomic<T, false> :
public atomic_traits<false>
2018 T operator =(T v)
volatile
2035 operator T()
volatile const
2045 bool is_lock_free()
const
2050 bool is_lock_free()
const volatile
2056 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
2063 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
2071 T load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
2081 T load(etl::memory_order order = etl::memory_order_seq_cst)
const
2091 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
2101 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
2112 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
2117 if (memcmp(&value, &expected,
sizeof(T)) == 0)
2131 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
2136 if (memcmp(&value, &expected,
sizeof(T)) == 0)
2150 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
2152 return compare_exchange_weak(expected, desired);
2155 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
2157 return compare_exchange_weak(expected, desired);
2161 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
2163 return compare_exchange_weak(expected, desired);
2166 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
2168 return compare_exchange_weak(expected, desired);
2171 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
2173 return compare_exchange_weak(expected, desired);
2176 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
2178 return compare_exchange_weak(expected, desired);
2187#undef ETL_SYNC_BUILTIN_LOCK
2188#undef ETL_SYNC_BUILTIN_UNLOCK
2205#if ETL_HAS_NATIVE_CHAR8_T
2208#if ETL_HAS_NATIVE_CHAR16_T
2211#if ETL_HAS_NATIVE_CHAR32_T
2214#if ETL_USING_8BIT_TYPES
2222#if ETL_USING_64BIT_TYPES
2232#if ETL_USING_64BIT_TYPES
2242#if ETL_USING_64BIT_TYPES
is_integral
Definition type_traits_generator.h:996
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
ETL_CONSTEXPR pair()
Default constructor.
Definition utility.h:176