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"
41 #if defined(ETL_COMPILER_GCC)
42 #pragma GCC diagnostic push
43 #pragma GCC diagnostic ignored "-Wunused-parameter"
44 #pragma GCC diagnostic ignored "-Wunused-value"
54 typedef enum memory_order
92 T operator =(T v)
volatile
102 return __sync_add_and_fetch(&value, 1);
105 T operator ++()
volatile
107 return __sync_add_and_fetch(&value, 1);
113 return __sync_fetch_and_add(&value, 1);
116 T operator ++(
int)
volatile
118 return __sync_fetch_and_add(&value, 1);
124 return __sync_sub_and_fetch(&value, 1);
127 T operator --()
volatile
129 return __sync_sub_and_fetch(&value, 1);
135 return __sync_fetch_and_sub(&value, 1);
138 T operator --(
int)
volatile
140 return __sync_fetch_and_sub(&value, 1);
146 return __sync_fetch_and_add(&value, v);
149 T operator +=(T v)
volatile
151 return __sync_fetch_and_add(&value, v);
157 return __sync_fetch_and_sub(&value, v);
160 T operator -=(T v)
volatile
162 return __sync_fetch_and_sub(&value, v);
168 return __sync_fetch_and_and(&value, v);
171 T operator &=(T v)
volatile
173 return __sync_fetch_and_and(&value, v);
179 return __sync_fetch_and_or(&value, v);
182 T operator |=(T v)
volatile
184 return __sync_fetch_and_or(&value, v);
190 return __sync_fetch_and_xor(&value, v);
193 T operator ^=(T v)
volatile
195 return __sync_fetch_and_xor(&value, v);
201 return __sync_fetch_and_add(&value, 0);
204 operator T()
volatile const
206 return __sync_fetch_and_add(&value, 0);
210 bool is_lock_free()
const
215 bool is_lock_free()
const volatile
221 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
223 (void)__sync_lock_test_and_set(&value, v);
226 void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
228 (void)__sync_lock_test_and_set(&value, v);
232 T load(etl::memory_order order = etl::memory_order_seq_cst)
const
234 return __sync_fetch_and_add(&value, 0);
237 T load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
239 return __sync_fetch_and_add(&value, 0);
243 T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst)
245 return __sync_fetch_and_add(&value, v);
248 T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
250 return __sync_fetch_and_add(&value, v);
254 T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst)
256 return __sync_fetch_and_sub(&value, v);
259 T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
261 return __sync_fetch_and_sub(&value, v);
265 T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst)
267 return __sync_fetch_and_or(&value, v);
270 T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
272 return __sync_fetch_and_or(&value, v);
276 T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst)
278 return __sync_fetch_and_and(&value, v);
281 T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
283 return __sync_fetch_and_and(&value, v);
287 T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst)
289 return __sync_fetch_and_xor(&value, v);
292 T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
294 return __sync_fetch_and_xor(&value, v);
298 T exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
300 return __sync_lock_test_and_set(&value, v);
303 T exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
305 return __sync_lock_test_and_set(&value, v);
309 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
311 T old = __sync_val_compare_and_swap(&value, expected, desired);
324 bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
326 T old = __sync_val_compare_and_swap(&value, expected, desired);
339 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
341 T old = __sync_val_compare_and_swap(&value, expected, desired);
354 bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
356 T old = __sync_val_compare_and_swap(&value, expected, desired);
370 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
374 while (!compare_exchange_weak(old, desired))
376 if (memcmp(&old, &expected,
sizeof(T)))
386 bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
390 while (!compare_exchange_weak(old, desired))
392 if (memcmp(&old, &expected,
sizeof(T)))
402 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
406 while (!compare_exchange_weak(old, desired))
408 if (memcmp(&old, &expected,
sizeof(T)))
418 bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
volatile
422 while (!compare_exchange_weak(old, desired))
424 if (memcmp(&old, &expected,
sizeof(T)))
439 mutable volatile T value;
445 template <
typename T>
456 : value(uintptr_t(v))
468 T* operator =(T* v)
volatile
478 return (T*)__sync_add_and_fetch(&value,
sizeof(T));
481 T* operator ++()
volatile
483 return (T*)__sync_add_and_fetch(&value,
sizeof(T));
489 return (T*)__sync_fetch_and_add(&value,
sizeof(T));
492 T* operator ++(
int)
volatile
494 return (T*)__sync_fetch_and_add(&value,
sizeof(T));
500 return (T*)__sync_sub_and_fetch(&value,
sizeof(T));
503 T* operator --()
volatile
505 return (T*)__sync_sub_and_fetch(&value,
sizeof(T));
511 return (T*)__sync_fetch_and_sub(&value,
sizeof(T));
514 T* operator --(
int)
volatile
516 return (T*)__sync_fetch_and_sub(&value,
sizeof(T));
520 T* operator +=(ptrdiff_t v)
522 return (T*)__sync_fetch_and_add(&value, v *
sizeof(T));
525 T* operator +=(ptrdiff_t v)
volatile
527 return (T*)__sync_fetch_and_add(&value, v *
sizeof(T));
531 T* operator -=(ptrdiff_t v)
533 return (T*)__sync_fetch_and_sub(&value, v *
sizeof(T));
536 T* operator -=(ptrdiff_t v)
volatile
538 return (T*)__sync_fetch_and_sub(&value, v *
sizeof(T));
544 return (T*)__sync_fetch_and_add(&value, 0);
547 operator T*()
volatile const
549 return (T*)__sync_fetch_and_add(&value, 0);
553 bool is_lock_free()
const
558 bool is_lock_free()
const volatile
564 void store(T* v, etl::memory_order order = etl::memory_order_seq_cst)
566 __sync_lock_test_and_set(&value, uintptr_t(v));
569 void store(T* v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
571 __sync_lock_test_and_set(&value, uintptr_t(v));
575 T* load(etl::memory_order order = etl::memory_order_seq_cst)
const
577 return (T*)__sync_fetch_and_add(&value, 0);
580 T* load(etl::memory_order order = etl::memory_order_seq_cst)
const volatile
582 return (T*)__sync_fetch_and_add(&value, 0);
586 T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
588 return (T*)__sync_fetch_and_add(&value, v);
591 T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
593 return (T*)__sync_fetch_and_add(&value, v);
597 T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
599 return (T*)__sync_fetch_and_sub(&value, v);
602 T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
604 return (T*)__sync_fetch_and_sub(&value, v);
608 T*
exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst)
610 return (T*)__sync_lock_test_and_set(&value, uintptr_t(v));
613 T*
exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst)
volatile
615 return (T*)__sync_lock_test_and_set(&value, uintptr_t(v));
619 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
621 T* old = (T*)__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired));
634 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
636 T* old = (T*)__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired));
649 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
651 T* old = (T*)__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired));
664 bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
volatile
666 T* old = (T*)__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired));
680 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
684 while (!compare_exchange_weak(old, desired))
686 if (memcmp(&old, &expected,
sizeof(T*)))
696 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
volatile
700 while (!compare_exchange_weak(old, desired))
702 if (memcmp(&old, &expected,
sizeof(T*)))
712 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
716 while (!compare_exchange_weak(old, desired))
718 if (memcmp(&old, &expected,
sizeof(T*)))
728 bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
volatile
732 while (!compare_exchange_weak(old, desired))
734 if (memcmp(&old, &expected,
sizeof(T*)))
749 mutable uintptr_t value;
766 #if ETL_USING_8BIT_TYPES
774 #if ETL_USING_64BIT_TYPES
784 #if ETL_USING_64BIT_TYPES
794 #if ETL_USING_64BIT_TYPES
806 #if defined(ETL_COMPILER_GCC)
807 #pragma GCC diagnostic pop
For all types except bool and pointers.
Definition: atomic_gcc_sync.h:69
is_integral
Definition: type_traits_generator.h:941
Definition: absolute.h:37
T exchange(T &object, const T &new_value)
exchange (const)
Definition: utility.h:301