diff --git a/include/nuttx/compiler.h b/include/nuttx/compiler.h index 0c2af726c15..32a2a96d765 100644 --- a/include/nuttx/compiler.h +++ b/include/nuttx/compiler.h @@ -656,6 +656,31 @@ # define memory_barrier() __asm__ __volatile__ ("" : : : "memory") +/* Atomic functions. */ + +# ifdef CONFIG_LIBC_ATOMIC_TOOLCHAIN +# define atomic_store_4(obj, val, memorder) __atomic_store_n(obj, val, memorder) +# define atomic_store_8(obj, val, memorder) __atomic_store_n(obj, val, memorder) +# define atomic_load_4(obj, memorder) __atomic_load_n(obj, memorder) +# define atomic_load_8(obj, memorder) __atomic_load_n(obj, memorder) +# define atomic_fetch_add_4(obj, val, memorder) __atomic_fetch_add(obj, val, memorder) +# define atomic_fetch_add_8(obj, val, memorder) __atomic_fetch_add(obj, val, memorder) +# define atomic_fetch_sub_4(obj, val, memorder) __atomic_fetch_sub(obj, val, memorder) +# define atomic_fetch_sub_8(obj, val, memorder) __atomic_fetch_sub(obj, val, memorder) +# define atomic_fetch_and_4(obj, val, memorder) __atomic_fetch_and(obj, val, memorder) +# define atomic_fetch_and_8(obj, val, memorder) __atomic_fetch_and(obj, val, memorder) +# define atomic_fetch_or_4(obj, val, memorder) __atomic_fetch_or(obj, val, memorder) +# define atomic_fetch_or_8(obj, val, memorder) __atomic_fetch_or(obj, val, memorder) +# define atomic_fetch_xor_4(obj, val, memorder) __atomic_fetch_xor(obj, val, memorder) +# define atomic_fetch_xor_8(obj, val, memorder) __atomic_fetch_xor(obj, val, memorder) +# define atomic_exchange_4(obj, val, memorder) __atomic_exchange_n(obj, val, memorder) +# define atomic_exchange_8(obj, val, memorder) __atomic_exchange_n(obj, val, memorder) +# define atomic_compare_exchange_4(obj, expected, desired, weak, success, failure) \ + __atomic_compare_exchange_n(obj, expected, desired, weak, success, failure) +# define atomic_compare_exchange_8(obj, expected, desired, weak, success, failure) \ + __atomic_compare_exchange_n(obj, expected, desired, weak, success, failure) +# endif + /* SDCC-specific definitions ************************************************/ #elif defined(SDCC) || defined(__SDCC) @@ -1211,6 +1236,47 @@ # define LDBL_MANT_DIG 53 +/* Atomic functions. */ + +# ifdef CONFIG_LIBC_ATOMIC_TOOLCHAIN +# define atomic_store_4(obj, val, memorder) \ + _InterlockedExchange((FAR long volatile *)(obj), val) +# define atomic_store_8(obj, val, memorder) \ + _InterlockedExchange64((FAR long long volatile *)(obj), val) +# define atomic_load_4(obj, memorder) \ + _InterlockedOr((FAR long volatile *)(obj), 0) +# define atomic_load_8(obj, memorder) \ + _InterlockedOr64((FAR long long volatile *)(obj), 0) +# define atomic_fetch_add_4(obj, val, memorder) \ + _InterlockedExchangeAdd((FAR long volatile *)(obj), val) +# define atomic_fetch_add_8(obj, val, memorder) \ + _InterlockedExchangeAdd64((FAR long long volatile *)(obj), val) +# define atomic_fetch_sub_4(obj, val, memorder) \ + _InterlockedExchangeAdd((FAR long volatile *)(obj), -val) +# define atomic_fetch_sub_8(obj, val, memorder) \ + _InterlockedExchangeAdd64((FAR long long volatile *)(obj), -val) +# define atomic_fetch_and_4(obj, val, memorder) \ + _InterlockedAnd((FAR long volatile *)(obj), val) +# define atomic_fetch_and_8(obj, val, memorder) \ + _InterlockedAnd64((FAR long long volatile *)(obj), val) +# define atomic_fetch_or_4(obj, val, memorder) \ + _InterlockedOr((FAR long volatile *)(obj), val) +# define atomic_fetch_or_8(obj, val, memorder) \ + _InterlockedOr64((FAR long long volatile *)(obj), val) +# define atomic_fetch_xor_4(obj, val, memorder) \ + _InterlockedXor((FAR long volatile *)(obj), val) +# define atomic_fetch_xor_8(obj, val, memorder) \ + _InterlockedXor64((FAR long long volatile *)(obj), val) +# define atomic_exchange_4(obj, val, memorder) \ + _InterlockedExchange((FAR long volatile *)(obj), val) +# define atomic_exchange_8(obj, val, memorder) \ + _InterlockedExchange64((FAR long long volatile *)(obj), val) +# define atomic_compare_exchange_4(obj, expect, desired, weak, success, failure) \ + (_InterlockedCompareExchange((FAR long volatile *)(obj), desired, *expect) == *expect) +# define atomic_compare_exchange_8(obj, expect, desired, weak, success, failure) \ + (_InterlockedCompareExchange64((FAR long long volatile *)(obj), desired, *expect) == *expect) +# endif + /* TASKING (Infineon AURIX C/C++)-specific definitions **********************/ #elif defined(__TASKING__) @@ -1314,6 +1380,49 @@ # define memory_barrier() __asm__ __volatile__ ("" : : : "memory") +/* Atomic functions. */ + +# ifdef CONFIG_LIBC_ATOMIC_TOOLCHAIN +# define atomic_store_4(obj, val, memorder) \ + __c11_atomic_store((FAR volatile _Atomic int32_t*)obj, val, memorder) +# define atomic_store_8(obj, val, memorder) \ + __c11_atomic_store((FAR volatile _Atomic int64_t*)obj, val, memorder) +# define atomic_load_4(obj, memorder) \ + __c11_atomic_load((FAR volatile _Atomic int32_t*)obj, memorder) +# define atomic_load_8(obj, memorder) \ + __c11_atomic_load((FAR volatile _Atomic int64_t*)obj, memorder) +# define atomic_fetch_add_4(obj, val, memorder) \ + __c11_atomic_fetch_add((FAR volatile _Atomic int32_t*)obj, val, memorder) +# define atomic_fetch_add_8(obj, val, memorder) \ + __c11_atomic_fetch_add((FAR volatile _Atomic int64_t*)obj, val, memorder) +# define atomic_fetch_sub_4(obj, val, memorder) \ + __c11_atomic_fetch_sub((FAR volatile _Atomic int32_t*)obj, val, memorder) +# define atomic_fetch_sub_8(obj, val, memorder) \ + __c11_atomic_fetch_sub((FAR volatile _Atomic int64_t*)obj, val, memorder) +# define atomic_fetch_and_4(obj, val, memorder) \ + __c11_atomic_fetch_and((FAR volatile _Atomic int32_t*)obj, val, memorder) +# define atomic_fetch_and_8(obj, val, memorder) \ + __c11_atomic_fetch_and((FAR volatile _Atomic int64_t*)obj, val, memorder) +# define atomic_fetch_or_4(obj, val, memorder) \ + __c11_atomic_fetch_or((FAR volatile _Atomic int32_t*)obj, val, memorder) +# define atomic_fetch_or_8(obj, val, memorder) \ + __c11_atomic_fetch_or((FAR volatile _Atomic int64_t*)obj, val, memorder) +# define atomic_fetch_xor_4(obj, val, memorder) \ + __c11_atomic_fetch_xor((FAR volatile _Atomic int32_t*)obj, val, memorder) +# define atomic_fetch_xor_8(obj, val, memorder) \ + __c11_atomic_fetch_xor((FAR volatile _Atomic int64_t*)obj, val, memorder) +# define atomic_exchange_4(obj, val, memorder) \ + __c11_atomic_exchange((FAR volatile _Atomic int32_t*)obj, val, memorder) +# define atomic_exchange_8(obj, val, memorder) \ + __c11_atomic_exchange((FAR volatile _Atomic int64_t*)obj, val, memorder) +# define atomic_compare_exchange_4(obj, expected, desired, weak, success, failure) \ + ((weak) ? __c11_atomic_compare_exchange_weak((FAR volatile _Atomic int32_t*)obj, expected, desired, success, failure) \ + : __c11_atomic_compare_exchange_strong((FAR volatile _Atomic int32_t*)obj, expected, desired, success, failure)) +# define atomic_compare_exchange_8(obj, expected, desired, weak, success, failure) \ + ((weak) ? __c11_atomic_compare_exchange_weak((FAR volatile _Atomic int64_t*)obj, expected, desired, success, failure) \ + : __c11_atomic_compare_exchange_strong((FAR volatile _Atomic int64_t*)obj, expected, desired, success, failure)) +# endif + /* Unknown compiler *********************************************************/ #else