29#ifndef ETL_ATOMIC_GCC_SYNC_INCLUDED
30#define ETL_ATOMIC_GCC_SYNC_INCLUDED
36#include "../static_assert.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 \
80 while (__atomic_test_and_set(&flag, etl::memory_order_seq_cst)) \
84 #define ETL_BUILTIN_UNLOCK \
86 __atomic_clear(&flag, etl::memory_order_seq_cst); \
94 typedef enum memory_order
96 memory_order_relaxed = __ATOMIC_RELAXED,
97 memory_order_consume = __ATOMIC_CONSUME,
98 memory_order_acquire = __ATOMIC_ACQUIRE,
99 memory_order_release = __ATOMIC_RELEASE,
100 memory_order_acq_rel = __ATOMIC_ACQ_REL,
101 memory_order_seq_cst = __ATOMIC_SEQ_CST
104 template <
bool Is_Always_Lock_Free>
107 static ETL_CONSTANT
bool is_always_lock_free = Is_Always_Lock_Free;
110 template <
bool Is_Always_Lock_Free>
111 ETL_CONSTANT
bool atomic_traits<Is_Always_Lock_Free>::is_always_lock_free;
116 template <typename T, bool integral_type = etl::is_integral<T>::value>
117 class atomic :
public atomic_traits<integral_type>
139 T operator=(T v)
volatile
149 return __atomic_add_fetch(&value, 1, etl::memory_order_seq_cst);
152 T operator++()
volatile
154 return __atomic_add_fetch(&value, 1, etl::memory_order_seq_cst);
160 return __atomic_fetch_add(&value, 1, etl::memory_order_seq_cst);
163 T operator++(
int)
volatile
165 return __atomic_fetch_add(&value, 1, etl::memory_order_seq_cst);
171 return __atomic_sub_fetch(&value, 1, etl::memory_order_seq_cst);
174 T operator--()
volatile
176 return __atomic_sub_fetch(&value, 1, etl::memory_order_seq_cst);
182 return __atomic_fetch_sub(&value, 1, etl::memory_order_seq_cst);
185 T operator--(
int)
volatile
187 return __atomic_fetch_sub(&value, 1, etl::memory_order_seq_cst);
193 return __atomic_fetch_add(&value, v, etl::memory_order_seq_cst);
196 T operator+=(T v)
volatile
198 return __atomic_fetch_add(&value, v, etl::memory_order_seq_cst);
204 return __atomic_fetch_sub(&value, v, etl::memory_order_seq_cst);
207 T operator-=(T v)
volatile
209 return __atomic_fetch_sub(&value, v, etl::memory_order_seq_cst);
215 return __atomic_fetch_and(&value, v, etl::memory_order_seq_cst);
220 return __atomic_fetch_and(&value, v, etl::memory_order_seq_cst);
226 return __atomic_fetch_or(&value, v, etl::memory_order_seq_cst);
231 return __atomic_fetch_or(&value, v, etl::memory_order_seq_cst);
237 return __atomic_fetch_xor(&value, v, etl::memory_order_seq_cst);
242 return __atomic_fetch_xor(&value, v, etl::memory_order_seq_cst);
248 return __atomic_fetch_add(&value, 0, etl::memory_order_seq_cst);
251 operator T()
volatile const
253 return __atomic_fetch_add(&value, 0, etl::memory_order_seq_cst);
257 bool is_lock_free()
const
262 bool is_lock_free()
const volatile
268 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
270 __atomic_store_n(&value, v, order);
273 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
275 __atomic_store_n(&value, v, order);
279 T load(etl::memory_order order = etl::memory_order_seq_cst)
const
281 return __atomic_load_n(&value, order);
284 T load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
286 return __atomic_load_n(&value, order);
290 T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst)
292 return __atomic_fetch_add(&value, v, order);
295 T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
297 return __atomic_fetch_add(&value, v, order);
301 T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst)
303 return __atomic_fetch_sub(&value, v, order);
306 T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
308 return __atomic_fetch_sub(&value, v, order);
312 T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst)
314 return __atomic_fetch_or(&value, v, order);
317 T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
319 return __atomic_fetch_or(&value, v, order);
323 T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst)
325 return __atomic_fetch_and(&value, v, order);
328 T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
330 return __atomic_fetch_and(&value, v, order);
334 T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst)
336 return __atomic_fetch_xor(&value, v, order);
339 T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
341 return __atomic_fetch_xor(&value, v, order);
345 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
347 return __atomic_exchange_n(&value, v, order);
350 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
352 return __atomic_exchange_n(&value, v, order);
356 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
358 return __atomic_compare_exchange_n(&value, &expected, desired,
true, order, order);
361 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
363 return __atomic_compare_exchange_n(&value, &expected, desired,
true, order, order);
366 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
368 return __atomic_compare_exchange_n(&value, &expected, desired,
true, success, failure);
371 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
373 return __atomic_compare_exchange_n(&value, &expected, desired,
true, success, failure);
377 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
379 return __atomic_compare_exchange_n(&value, &expected, desired,
false, order, order);
382 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
384 return __atomic_compare_exchange_n(&value, &expected, desired,
false, order, order);
387 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
389 return __atomic_compare_exchange_n(&value, &expected, desired,
false, success, failure);
392 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
394 return __atomic_compare_exchange_n(&value, &expected, desired,
false, success, failure);
399 atomic& operator=(
const atomic&) ETL_DELETE;
400 atomic& operator=(
const atomic&)
volatile ETL_DELETE;
408 template <
typename T>
409 class atomic<T*,
false> :
public atomic_traits<true>
419 : value(uintptr_t(v))
431 T* operator=(T* v)
volatile
441 return reinterpret_cast<T*
>(__atomic_add_fetch(&value,
sizeof(T), etl::memory_order_seq_cst));
444 T* operator++()
volatile
446 return reinterpret_cast<T*
>(__atomic_add_fetch(&value,
sizeof(T), etl::memory_order_seq_cst));
452 return reinterpret_cast<T*
>(__atomic_fetch_add(&value,
sizeof(T), etl::memory_order_seq_cst));
455 T* operator++(
int)
volatile
457 return reinterpret_cast<T*
>(__atomic_fetch_add(&value,
sizeof(T), etl::memory_order_seq_cst));
463 return reinterpret_cast<T*
>(__atomic_sub_fetch(&value,
sizeof(T), etl::memory_order_seq_cst));
466 T* operator--()
volatile
468 return reinterpret_cast<T*
>(__atomic_sub_fetch(&value,
sizeof(T), etl::memory_order_seq_cst));
474 return reinterpret_cast<T*
>(__atomic_fetch_sub(&value,
sizeof(T), etl::memory_order_seq_cst));
477 T* operator--(
int)
volatile
479 return reinterpret_cast<T*
>(__atomic_fetch_sub(&value,
sizeof(T), etl::memory_order_seq_cst));
483 T* operator+=(ptrdiff_t v)
485 return reinterpret_cast<T*
>(
486 __atomic_fetch_add(&value,
static_cast<uintptr_t
>(v *
static_cast<ptrdiff_t
>(
sizeof(T))), etl::memory_order_seq_cst));
489 T* operator+=(ptrdiff_t v)
volatile
491 return reinterpret_cast<T*
>(
492 __atomic_fetch_add(&value,
static_cast<uintptr_t
>(v *
static_cast<ptrdiff_t
>(
sizeof(T))), etl::memory_order_seq_cst));
496 T* operator-=(ptrdiff_t v)
498 return reinterpret_cast<T*
>(
499 __atomic_fetch_sub(&value,
static_cast<uintptr_t
>(v *
static_cast<ptrdiff_t
>(
sizeof(T))), etl::memory_order_seq_cst));
502 T* operator-=(ptrdiff_t v)
volatile
504 return reinterpret_cast<T*
>(
505 __atomic_fetch_sub(&value,
static_cast<uintptr_t
>(v *
static_cast<ptrdiff_t
>(
sizeof(T))), etl::memory_order_seq_cst));
511 return reinterpret_cast<T*
>(__atomic_fetch_add(&value, 0, etl::memory_order_seq_cst));
514 operator T*()
volatile const
516 return reinterpret_cast<T*
>(__atomic_fetch_add(&value, 0, etl::memory_order_seq_cst));
520 bool is_lock_free()
const
525 bool is_lock_free()
const volatile
531 void store(T* v, etl::memory_order order = etl::memory_order_seq_cst)
533 __atomic_store_n(&value, uintptr_t(v), order);
536 void store(T* v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
538 __atomic_store_n(&value, uintptr_t(v), order);
542 T* load(etl::memory_order order = etl::memory_order_seq_cst)
const
544 return reinterpret_cast<T*
>(__atomic_load_n(&value, order));
547 T* load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
549 return reinterpret_cast<T*
>(__atomic_load_n(&value, order));
553 T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
555 return reinterpret_cast<T*
>(__atomic_fetch_add(&value,
static_cast<uintptr_t
>(v *
static_cast<ptrdiff_t
>(
sizeof(T))), order));
558 T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
560 return reinterpret_cast<T*
>(__atomic_fetch_add(&value,
static_cast<uintptr_t
>(v *
static_cast<ptrdiff_t
>(
sizeof(T))), order));
564 T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
566 return reinterpret_cast<T*
>(__atomic_fetch_sub(&value,
static_cast<uintptr_t
>(v *
static_cast<ptrdiff_t
>(
sizeof(T))), order));
569 T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
571 return reinterpret_cast<T*
>(__atomic_fetch_sub(&value,
static_cast<uintptr_t
>(v *
static_cast<ptrdiff_t
>(
sizeof(T))), order));
575 T*
exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst)
577 return reinterpret_cast<T*
>(__atomic_exchange_n(&value, uintptr_t(v), order));
580 T*
exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
582 return reinterpret_cast<T*
>(__atomic_exchange_n(&value, uintptr_t(v), order));
586 bool compare_exchange_weak(T*&
expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
588 uintptr_t expected_v = uintptr_t(
expected);
590 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
true, order, order);
593 bool compare_exchange_weak(T*&
expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
595 uintptr_t expected_v = uintptr_t(
expected);
597 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
true, order, order);
600 bool compare_exchange_weak(T*&
expected, T* desired, etl::memory_order success, etl::memory_order failure)
602 uintptr_t expected_v = uintptr_t(
expected);
604 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
true, success, failure);
607 bool compare_exchange_weak(T*&
expected, T* desired, etl::memory_order success, etl::memory_order failure)
volatile
609 uintptr_t expected_v = uintptr_t(
expected);
611 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
true, success, failure);
615 bool compare_exchange_strong(T*&
expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
617 uintptr_t expected_v = uintptr_t(
expected);
619 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
false, order, order);
622 bool compare_exchange_strong(T*&
expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
624 uintptr_t expected_v = uintptr_t(
expected);
626 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
false, order, order);
629 bool compare_exchange_strong(T*&
expected, T* desired, etl::memory_order success, etl::memory_order failure)
631 uintptr_t expected_v = uintptr_t(
expected);
633 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
false, success, failure);
636 bool compare_exchange_strong(T*&
expected, T* desired, etl::memory_order success, etl::memory_order failure)
volatile
638 uintptr_t expected_v = uintptr_t(
expected);
640 return __atomic_compare_exchange_n(&value, &expected_v, uintptr_t(desired),
false, success, failure);
645 atomic& operator=(
const atomic&) ETL_DELETE;
646 atomic& operator=(
const atomic&)
volatile ETL_DELETE;
648 mutable uintptr_t value;
655 class atomic<bool, true> :
public atomic_traits<true>
670 bool operator=(
bool v)
677 bool operator=(
bool v)
volatile
685 operator bool()
const
687 return static_cast<bool>(__atomic_fetch_add(&value, 0, etl::memory_order_seq_cst));
690 operator bool()
volatile const
692 return static_cast<bool>(__atomic_fetch_add(&value, 0, etl::memory_order_seq_cst));
696 bool is_lock_free()
const
701 bool is_lock_free()
const volatile
707 void store(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
709 __atomic_store_n(&value,
char(v), order);
712 void store(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
714 __atomic_store_n(&value,
char(v), order);
718 bool load(etl::memory_order order = etl::memory_order_seq_cst)
const
720 return static_cast<bool>(__atomic_load_n(&value, order));
723 bool load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
725 return static_cast<bool>(__atomic_load_n(&value, order));
729 bool exchange(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
731 return static_cast<bool>(__atomic_exchange_n(&value,
char(v), order));
734 bool exchange(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
736 return static_cast<bool>(__atomic_exchange_n(&value,
char(v), order));
740 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
742 char expected_v = char(expected);
743 char desired_v = char(desired);
745 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
true, order, order);
748 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
750 char expected_v = char(expected);
751 char desired_v = char(desired);
753 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
true, order, order);
756 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
758 char expected_v = char(expected);
759 char desired_v = char(desired);
761 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
true, success, failure);
764 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
volatile
766 char expected_v = char(expected);
767 char desired_v = char(desired);
769 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
true, success, failure);
773 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
775 char expected_v = char(expected);
776 char desired_v = char(desired);
778 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
false, order, order);
781 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
783 char expected_v = char(expected);
784 char desired_v = char(desired);
786 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
false, order, order);
789 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
791 char expected_v = char(expected);
792 char desired_v = char(desired);
794 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
false, success, failure);
797 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
volatile
799 char expected_v = char(expected);
800 char desired_v = char(desired);
802 return __atomic_compare_exchange_n(&value, &expected_v, desired_v,
false, success, failure);
807 atomic& operator=(
const atomic&) ETL_DELETE;
808 atomic& operator=(
const atomic&)
volatile ETL_DELETE;
817 template <
typename T>
818 class atomic<T, false> :
public atomic_traits<false>
822 ETL_STATIC_ASSERT((etl::is_trivially_copyable<T>::value),
"atomic<T> requires that T is trivially copyable");
823 ETL_STATIC_ASSERT((etl::is_copy_constructible<T>::value),
"atomic<T> requires that T is copy constructible");
824 ETL_STATIC_ASSERT((etl::is_copy_assignable<T>::value),
"atomic<T> requires that T is copy assignable");
825 ETL_STATIC_ASSERT((etl::is_move_constructible<T>::value),
"atomic<T> requires that T is move constructible");
826 ETL_STATIC_ASSERT((etl::is_move_assignable<T>::value),
"atomic<T> requires that T is move assignable");
827 ETL_STATIC_ASSERT((etl::is_same<T,
typename etl::remove_cv<T>::type>::value),
"atomic<T> requires that T is not const or volatile");
860 bool is_lock_free()
const
866 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
875 T load(etl::memory_order order = etl::memory_order_seq_cst)
const
886 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
898 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
904 if (memcmp(&value, &expected,
sizeof(T)) == 0)
918 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
922 return compare_exchange_weak(expected, desired);
926 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
929 return compare_exchange_weak(expected, desired);
932 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
936 return compare_exchange_weak(expected, desired);
941 atomic& operator=(
const atomic&) ETL_DELETE;
942 atomic& operator=(
const atomic&)
volatile ETL_DELETE;
948 #undef ETL_BUILTIN_LOCK
949 #undef ETL_BUILTIN_UNLOCK
953#if defined(ETL_USE_SYNC_BUILTINS)
955 #define ETL_BUILTIN_LOCK \
957 while (__sync_lock_test_and_set(&flag, 1U)) \
961 #define ETL_BUILTIN_UNLOCK \
963 __sync_lock_release(&flag); \
971 typedef enum memory_order
973 memory_order_relaxed,
974 memory_order_consume,
975 memory_order_acquire,
976 memory_order_release,
977 memory_order_acq_rel,
981 template <
bool Is_Always_Lock_Free>
984 static ETL_CONSTANT
bool is_always_lock_free = Is_Always_Lock_Free;
987 template <
bool Is_Always_Lock_Free>
988 ETL_CONSTANT
bool atomic_traits<Is_Always_Lock_Free>::is_always_lock_free;
993 template <typename T, bool integral_type = etl::is_integral<T>::value>
994 class atomic :
public atomic_traits<integral_type>
998 ETL_STATIC_ASSERT(etl::is_integral<T>::value,
"Only integral types are supported");
1018 T operator=(T v)
volatile
1028 return __sync_add_and_fetch(&value, 1);
1031 T operator++()
volatile
1033 return __sync_add_and_fetch(&value, 1);
1039 return __sync_fetch_and_add(&value, 1);
1042 T operator++(
int)
volatile
1044 return __sync_fetch_and_add(&value, 1);
1050 return __sync_sub_and_fetch(&value, 1);
1053 T operator--()
volatile
1055 return __sync_sub_and_fetch(&value, 1);
1061 return __sync_fetch_and_sub(&value, 1);
1064 T operator--(
int)
volatile
1066 return __sync_fetch_and_sub(&value, 1);
1072 return __sync_fetch_and_add(&value, v);
1075 T operator+=(T v)
volatile
1077 return __sync_fetch_and_add(&value, v);
1083 return __sync_fetch_and_sub(&value, v);
1086 T operator-=(T v)
volatile
1088 return __sync_fetch_and_sub(&value, v);
1094 return __sync_fetch_and_and(&value, v);
1099 return __sync_fetch_and_and(&value, v);
1105 return __sync_fetch_and_or(&value, v);
1110 return __sync_fetch_and_or(&value, v);
1116 return __sync_fetch_and_xor(&value, v);
1121 return __sync_fetch_and_xor(&value, v);
1127 return __sync_fetch_and_add(&value, 0);
1130 operator T()
volatile const
1132 return __sync_fetch_and_add(&value, 0);
1136 bool is_lock_free()
const
1141 bool is_lock_free()
const volatile
1147 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
1150 (void)__sync_lock_test_and_set(&value, v);
1153 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1156 (void)__sync_lock_test_and_set(&value, v);
1160 T load(etl::memory_order order = etl::memory_order_seq_cst)
const
1163 return __sync_fetch_and_add(&value, 0);
1166 T load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
1169 return __sync_fetch_and_add(&value, 0);
1173 T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst)
1176 return __sync_fetch_and_add(&value, v);
1179 T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1182 return __sync_fetch_and_add(&value, v);
1186 T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst)
1189 return __sync_fetch_and_sub(&value, v);
1192 T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1195 return __sync_fetch_and_sub(&value, v);
1199 T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst)
1202 return __sync_fetch_and_or(&value, v);
1205 T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1208 return __sync_fetch_and_or(&value, v);
1212 T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst)
1215 return __sync_fetch_and_and(&value, v);
1218 T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1221 return __sync_fetch_and_and(&value, v);
1225 T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst)
1228 return __sync_fetch_and_xor(&value, v);
1231 T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1234 return __sync_fetch_and_xor(&value, v);
1238 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
1241 return __sync_lock_test_and_set(&value, v);
1244 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1247 return __sync_lock_test_and_set(&value, v);
1251 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
1254 T old = __sync_val_compare_and_swap(&value, expected, desired);
1256 if (old == expected)
1267 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1270 T old = __sync_val_compare_and_swap(&value, expected, desired);
1272 if (old == expected)
1283 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
1287 T old = __sync_val_compare_and_swap(&value, expected, desired);
1289 if (old == expected)
1300 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
1304 T old = __sync_val_compare_and_swap(&value, expected, desired);
1306 if (old == expected)
1318 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
1323 while (!compare_exchange_weak(old, desired))
1325 if (memcmp(&old, &expected,
sizeof(T)))
1335 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1340 while (!compare_exchange_weak(old, desired))
1342 if (memcmp(&old, &expected,
sizeof(T)))
1352 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
1358 while (!compare_exchange_weak(old, desired))
1360 if (memcmp(&old, &expected,
sizeof(T)))
1370 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
1376 while (!compare_exchange_weak(old, desired))
1378 if (memcmp(&old, &expected,
sizeof(T)))
1390 atomic& operator=(
const atomic&) ETL_DELETE;
1391 atomic& operator=(
const atomic&)
volatile ETL_DELETE;
1393 mutable volatile T value;
1399 template <
typename T>
1400 class atomic<T*,
false> :
public atomic_traits<true>
1410 : value(uintptr_t(v))
1422 T* operator=(T* v)
volatile
1432 return reinterpret_cast<T*
>(__sync_add_and_fetch(&value,
sizeof(T)));
1435 T* operator++()
volatile
1437 return reinterpret_cast<T*
>(__sync_add_and_fetch(&value,
sizeof(T)));
1443 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value,
sizeof(T)));
1446 T* operator++(
int)
volatile
1448 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value,
sizeof(T)));
1454 return reinterpret_cast<T*
>(__sync_sub_and_fetch(&value,
sizeof(T)));
1457 T* operator--()
volatile
1459 return reinterpret_cast<T*
>(__sync_sub_and_fetch(&value,
sizeof(T)));
1465 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value,
sizeof(T)));
1468 T* operator--(
int)
volatile
1470 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value,
sizeof(T)));
1474 T* operator+=(ptrdiff_t v)
1476 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, v *
sizeof(T)));
1479 T* operator+=(ptrdiff_t v)
volatile
1481 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, v *
sizeof(T)));
1485 T* operator-=(ptrdiff_t v)
1487 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value, v *
sizeof(T)));
1490 T* operator-=(ptrdiff_t v)
volatile
1492 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value, v *
sizeof(T)));
1498 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, 0));
1501 operator T*()
volatile const
1503 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, 0));
1507 bool is_lock_free()
const
1512 bool is_lock_free()
const volatile
1518 void store(T* v, etl::memory_order order = etl::memory_order_seq_cst)
1520 __sync_lock_test_and_set(&value, uintptr_t(v));
1523 void store(T* v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1525 __sync_lock_test_and_set(&value, uintptr_t(v));
1529 T* load(etl::memory_order order = etl::memory_order_seq_cst)
const
1531 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, 0));
1534 T* load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
1536 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, 0));
1540 T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
1542 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, v));
1545 T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1547 return reinterpret_cast<T*
>(__sync_fetch_and_add(&value, v));
1551 T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
1553 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value, v));
1556 T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1558 return reinterpret_cast<T*
>(__sync_fetch_and_sub(&value, v));
1562 T*
exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst)
1564 return reinterpret_cast<T*
>(__sync_lock_test_and_set(&value, uintptr_t(v)));
1567 T*
exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1569 return reinterpret_cast<T*
>(__sync_lock_test_and_set(&value, uintptr_t(v)));
1573 bool compare_exchange_weak(T*&
expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
1575 T* old =
reinterpret_cast<T*
>(__sync_val_compare_and_swap(&value, uintptr_t(
expected), uintptr_t(desired)));
1588 bool compare_exchange_weak(T*&
expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1590 T* old =
reinterpret_cast<T*
>(__sync_val_compare_and_swap(&value, uintptr_t(
expected), uintptr_t(desired)));
1603 bool compare_exchange_weak(T*&
expected, T* desired, etl::memory_order success, etl::memory_order failure)
1605 T* old =
reinterpret_cast<T*
>(__sync_val_compare_and_swap(&value, uintptr_t(
expected), uintptr_t(desired)));
1618 bool compare_exchange_weak(T*&
expected, T* desired, etl::memory_order success, etl::memory_order failure)
volatile
1620 T* old =
reinterpret_cast<T*
>(__sync_val_compare_and_swap(&value, uintptr_t(
expected), uintptr_t(desired)));
1634 bool compare_exchange_strong(T*&
expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
1638 while (!compare_exchange_weak(old, desired))
1640 if (memcmp(&old, &
expected,
sizeof(T*)))
1650 bool compare_exchange_strong(T*&
expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1654 while (!compare_exchange_weak(old, desired))
1656 if (memcmp(&old, &
expected,
sizeof(T*)))
1666 bool compare_exchange_strong(T*&
expected, T* desired, etl::memory_order success, etl::memory_order failure)
1670 while (!compare_exchange_weak(old, desired))
1672 if (memcmp(&old, &
expected,
sizeof(T*)))
1682 bool compare_exchange_strong(T*&
expected, T* desired, etl::memory_order success, etl::memory_order failure)
volatile
1686 while (!compare_exchange_weak(old, desired))
1688 if (memcmp(&old, &
expected,
sizeof(T*)))
1700 atomic& operator=(
const atomic&) ETL_DELETE;
1701 atomic& operator=(
const atomic&)
volatile ETL_DELETE;
1703 mutable uintptr_t value;
1710 class atomic<bool, true> :
public atomic_traits<true>
1725 bool operator=(
bool v)
1732 bool operator=(
bool v)
volatile
1740 operator bool()
const
1742 return static_cast<bool>(__sync_fetch_and_add(&value, 0));
1745 operator bool()
volatile const
1747 return static_cast<bool>(__sync_fetch_and_add(&value, 0));
1751 bool is_lock_free()
const
1756 bool is_lock_free()
const volatile
1762 void store(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
1764 __sync_lock_test_and_set(&value,
char(v));
1767 void store(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1769 __sync_lock_test_and_set(&value,
char(v));
1773 bool load(etl::memory_order order = etl::memory_order_seq_cst)
const
1775 return static_cast<bool>(__sync_fetch_and_add(&value, 0));
1778 bool load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
1780 return static_cast<bool>(__sync_fetch_and_add(&value, 0));
1784 bool exchange(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
1786 return static_cast<bool>(__sync_lock_test_and_set(&value,
char(v)));
1789 bool exchange(
bool v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1791 return static_cast<bool>(__sync_lock_test_and_set(&value,
char(v)));
1795 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
1797 bool old =
static_cast<bool>(__sync_val_compare_and_swap(&value,
char(expected),
char(desired)));
1799 if (old == expected)
1810 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1812 bool old =
static_cast<bool>(__sync_val_compare_and_swap(&value,
char(expected),
char(desired)));
1814 if (old == expected)
1825 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
1827 bool old =
static_cast<bool>(__sync_val_compare_and_swap(&value,
char(expected),
char(desired)));
1829 if (old == expected)
1840 bool compare_exchange_weak(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
volatile
1842 bool old =
static_cast<bool>(__sync_val_compare_and_swap(&value,
char(expected),
char(desired)));
1844 if (old == expected)
1856 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
1858 bool old = expected;
1860 while (!compare_exchange_weak(old, desired))
1862 if (memcmp(&old, &expected,
sizeof(
bool)))
1872 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
1874 bool old = expected;
1876 while (!compare_exchange_weak(old, desired))
1878 if (memcmp(&old, &expected,
sizeof(
bool)))
1888 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
1890 bool old = expected;
1892 while (!compare_exchange_weak(old, desired))
1894 if (memcmp(&old, &expected,
sizeof(
bool)))
1904 bool compare_exchange_strong(
bool& expected,
bool desired, etl::memory_order success, etl::memory_order failure)
volatile
1906 bool old = expected;
1908 while (!compare_exchange_weak(old, desired))
1910 if (memcmp(&old, &expected,
sizeof(
bool)))
1922 atomic& operator=(
const atomic&) ETL_DELETE;
1923 atomic& operator=(
const atomic&)
volatile ETL_DELETE;
1932 template <
typename T>
1933 class atomic<T, false> :
public atomic_traits<false>
1937 ETL_STATIC_ASSERT((etl::is_trivially_copyable<T>::value),
"atomic<T> requires that T is trivially copyable");
1938 ETL_STATIC_ASSERT((etl::is_copy_constructible<T>::value),
"atomic<T> requires that T is copy constructible");
1939 ETL_STATIC_ASSERT((etl::is_copy_assignable<T>::value),
"atomic<T> requires that T is copy assignable");
1940 ETL_STATIC_ASSERT((etl::is_move_constructible<T>::value),
"atomic<T> requires that T is move constructible");
1941 ETL_STATIC_ASSERT((etl::is_move_assignable<T>::value),
"atomic<T> requires that T is move assignable");
1942 ETL_STATIC_ASSERT((etl::is_same<T,
typename etl::remove_cv<T>::type>::value),
"atomic<T> requires that T is not const or volatile");
1975 bool is_lock_free()
const
1981 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
1989 T load(etl::memory_order order = etl::memory_order_seq_cst)
const
1999 T
exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
2010 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
2015 if (memcmp(&value, &expected,
sizeof(T)) == 0)
2029 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
2031 return compare_exchange_weak(expected, desired);
2035 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
2037 return compare_exchange_weak(expected, desired);
2040 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
2042 return compare_exchange_weak(expected, desired);
2047 atomic& operator=(
const atomic&) ETL_DELETE;
2048 atomic& operator=(
const atomic&)
volatile ETL_DELETE;
2054 #undef ETL_SYNC_BUILTIN_LOCK
2055 #undef ETL_SYNC_BUILTIN_UNLOCK
2059 typedef etl::atomic<bool> atomic_bool;
2060 typedef etl::atomic<char> atomic_char;
2061 typedef etl::atomic<signed char> atomic_schar;
2062 typedef etl::atomic<unsigned char> atomic_uchar;
2063 typedef etl::atomic<short> atomic_short;
2064 typedef etl::atomic<unsigned short> atomic_ushort;
2065 typedef etl::atomic<int> atomic_int;
2066 typedef etl::atomic<unsigned int> atomic_uint;
2067 typedef etl::atomic<long> atomic_long;
2068 typedef etl::atomic<unsigned long> atomic_ulong;
2069 typedef etl::atomic<long long> atomic_llong;
2070 typedef etl::atomic<unsigned long long> atomic_ullong;
2071 typedef etl::atomic<wchar_t> atomic_wchar_t;
2072#if ETL_HAS_NATIVE_CHAR8_T
2073 typedef etl::atomic<char8_t> atomic_char8_t;
2075#if ETL_HAS_NATIVE_CHAR16_T
2076 typedef etl::atomic<char16_t> atomic_char16_t;
2078#if ETL_HAS_NATIVE_CHAR32_T
2079 typedef etl::atomic<char32_t> atomic_char32_t;
2081#if ETL_USING_8BIT_TYPES
2082 typedef etl::atomic<uint8_t> atomic_uint8_t;
2083 typedef etl::atomic<int8_t> atomic_int8_t;
2085 typedef etl::atomic<uint16_t> atomic_uint16_t;
2086 typedef etl::atomic<int16_t> atomic_int16_t;
2087 typedef etl::atomic<uint32_t> atomic_uint32_t;
2088 typedef etl::atomic<int32_t> atomic_int32_t;
2089#if ETL_USING_64BIT_TYPES
2090 typedef etl::atomic<uint64_t> atomic_uint64_t;
2091 typedef etl::atomic<int64_t> atomic_int64_t;
2093 typedef etl::atomic<int_least8_t> atomic_int_least8_t;
2094 typedef etl::atomic<uint_least8_t> atomic_uint_least8_t;
2095 typedef etl::atomic<int_least16_t> atomic_int_least16_t;
2096 typedef etl::atomic<uint_least16_t> atomic_uint_least16_t;
2097 typedef etl::atomic<int_least32_t> atomic_int_least32_t;
2098 typedef etl::atomic<uint_least32_t> atomic_uint_least32_t;
2099#if ETL_USING_64BIT_TYPES
2100 typedef etl::atomic<int_least64_t> atomic_int_least64_t;
2101 typedef etl::atomic<uint_least64_t> atomic_uint_least64_t;
2103 typedef etl::atomic<int_fast8_t> atomic_int_fast8_t;
2104 typedef etl::atomic<uint_fast8_t> atomic_uint_fast8_t;
2105 typedef etl::atomic<int_fast16_t> atomic_int_fast16_t;
2106 typedef etl::atomic<uint_fast16_t> atomic_uint_fast16_t;
2107 typedef etl::atomic<int_fast32_t> atomic_int_fast32_t;
2108 typedef etl::atomic<uint_fast32_t> atomic_uint_fast32_t;
2109#if ETL_USING_64BIT_TYPES
2110 typedef etl::atomic<int_fast64_t> atomic_int_fast64_t;
2111 typedef etl::atomic<uint_fast64_t> atomic_uint_fast64_t;
2113 typedef etl::atomic<intptr_t> atomic_intptr_t;
2114 typedef etl::atomic<uintptr_t> atomic_uintptr_t;
2115 typedef etl::atomic<size_t> atomic_size_t;
2116 typedef etl::atomic<ptrdiff_t> atomic_ptrdiff_t;
2117 typedef etl::atomic<intmax_t> atomic_intmax_t;
2118 typedef etl::atomic<uintmax_t> atomic_uintmax_t;
Expected type.
Definition expected.h:257
bitset_ext
Definition absolute.h:40
T exchange(T &object, const T &new_value)
exchange (const)
Definition utility.h:497
etl::byte & operator^=(etl::byte &lhs, etl::byte rhs)
Exclusive or equals.
Definition byte.h:290
etl::byte & operator|=(etl::byte &lhs, etl::byte rhs)
Or equals.
Definition byte.h:274
etl::byte & operator&=(etl::byte &lhs, etl::byte rhs)
And equals.
Definition byte.h:282