arch_atomic : Introduce CONFIG_LIBC_ARCH_ATOMIC
Some armv7-m-based SoCs do not work with atomic instructions, even though armv7-m supports them. To avoid using atomic instructions generated by gcc, CONFIG_LIBC_ARCH_ATOMIC is newly introduced with which arch_atomic.c is linked explicitly. However, the function names need to be changed to avoid build errors, since the functions described in stdatomic.h are gcc built-in and inlined when the code is compiled. About libcxx with CONFIG_LIBC_ARCH_ATOMIC, it still does not work. It is also needed to call nx_atomic_ ver instead of __atomic ver in libcxx/include/__atomic/cxx_atomic_lmpl.h. Signed-off-by: Takuya Miyasita <Takuya.Miyashita@sony.com>
This commit is contained in:
parent
07c986905d
commit
2275138dcf
6 changed files with 482 additions and 388 deletions
|
|
@ -731,6 +731,7 @@ config ARCH_CHIP_CXD32XX
|
|||
bool "Sony CXD32xx"
|
||||
select ARCH_CORTEXM4
|
||||
select ARCH_HAVE_FPU
|
||||
select LIBC_ARCH_ATOMIC
|
||||
---help---
|
||||
Sony CXD32XX (ARM Cortex-M4) architectures
|
||||
|
||||
|
|
|
|||
|
|
@ -573,3 +573,7 @@ SHLDFLAGS = -shared -Bsymbolic -Bdynamic -G
|
|||
ifeq ($(CONFIG_SIM_M32),y)
|
||||
SHLDFLAGS += -melf_i386
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_LIBC_ARCH_ATOMIC),y)
|
||||
ARCHCFLAGS += -D__STDC_NO_ATOMICS__
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -63,38 +63,38 @@
|
|||
#define ATOMIC_VAR_INIT(value) (value)
|
||||
|
||||
#define atomic_store_n(obj, val, type) \
|
||||
(sizeof(*(obj)) == 1 ? __atomic_store_1(obj, val, type) : \
|
||||
sizeof(*(obj)) == 2 ? __atomic_store_2(obj, val, type) : \
|
||||
sizeof(*(obj)) == 4 ? __atomic_store_4(obj, val, type) : \
|
||||
__atomic_store_8(obj, val, type))
|
||||
(sizeof(*(obj)) == 1 ? nx_atomic_store_1(obj, val, type) : \
|
||||
sizeof(*(obj)) == 2 ? nx_atomic_store_2(obj, val, type) : \
|
||||
sizeof(*(obj)) == 4 ? nx_atomic_store_4(obj, val, type) : \
|
||||
nx_atomic_store_8(obj, val, type))
|
||||
|
||||
#define atomic_store(obj, val) atomic_store_n(obj, val, __ATOMIC_RELAXED)
|
||||
#define atomic_store_explicit(obj, val, type) atomic_store_n(obj, val, type)
|
||||
#define atomic_init(obj, val) atomic_store(obj, val)
|
||||
|
||||
#define atomic_load_n(obj, type) \
|
||||
(sizeof(*(obj)) == 1 ? __atomic_load_1(obj, type) : \
|
||||
sizeof(*(obj)) == 2 ? __atomic_load_2(obj, type) : \
|
||||
sizeof(*(obj)) == 4 ? __atomic_load_4(obj, type) : \
|
||||
__atomic_load_8(obj, type))
|
||||
(sizeof(*(obj)) == 1 ? nx_atomic_load_1(obj, type) : \
|
||||
sizeof(*(obj)) == 2 ? nx_atomic_load_2(obj, type) : \
|
||||
sizeof(*(obj)) == 4 ? nx_atomic_load_4(obj, type) : \
|
||||
nx_atomic_load_8(obj, type))
|
||||
|
||||
#define atomic_load(obj) atomic_load_n(obj, __ATOMIC_RELAXED)
|
||||
#define atomic_load_explicit(obj, type) atomic_load_n(obj, type)
|
||||
|
||||
#define atomic_exchange_n(obj, val, type) \
|
||||
(sizeof(*(obj)) == 1 ? __atomic_exchange_1(obj, val, type) : \
|
||||
sizeof(*(obj)) == 2 ? __atomic_exchange_2(obj, val, type) : \
|
||||
sizeof(*(obj)) == 4 ? __atomic_exchange_4(obj, val, type) : \
|
||||
__atomic_exchange_8(obj, val, type))
|
||||
(sizeof(*(obj)) == 1 ? nx_atomic_exchange_1(obj, val, type) : \
|
||||
sizeof(*(obj)) == 2 ? nx_atomic_exchange_2(obj, val, type) : \
|
||||
sizeof(*(obj)) == 4 ? nx_atomic_exchange_4(obj, val, type) : \
|
||||
nx_atomic_exchange_8(obj, val, type))
|
||||
|
||||
#define atomic_exchange(obj, val) atomic_exchange_n(obj, val, __ATOMIC_RELAXED)
|
||||
#define atomic_exchange_explicit(obj, val, type) atomic_exchange_n(obj, val, type)
|
||||
|
||||
#define atomic_compare_exchange_n(obj, expected, desired, weak, success, failure) \
|
||||
(sizeof(*(obj)) == 1 ? __atomic_compare_exchange_1(obj, expected, desired, weak, success, failure) : \
|
||||
sizeof(*(obj)) == 2 ? __atomic_compare_exchange_2(obj, expected, desired, weak, success, failure) : \
|
||||
sizeof(*(obj)) == 4 ? __atomic_compare_exchange_4(obj, expected, desired, weak, success, failure) : \
|
||||
__atomic_compare_exchange_8(obj, expected, desired, weak, success, failure))
|
||||
(sizeof(*(obj)) == 1 ? nx_atomic_compare_exchange_1(obj, expected, desired, weak, success, failure) : \
|
||||
sizeof(*(obj)) == 2 ? nx_atomic_compare_exchange_2(obj, expected, desired, weak, success, failure) : \
|
||||
sizeof(*(obj)) == 4 ? nx_atomic_compare_exchange_4(obj, expected, desired, weak, success, failure) : \
|
||||
nx_atomic_compare_exchange_8(obj, expected, desired, weak, success, failure))
|
||||
|
||||
#define atomic_compare_exchange_strong(obj, expected, desired) \
|
||||
atomic_compare_exchange_n(obj, expected, desired, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED)
|
||||
|
|
@ -106,10 +106,10 @@
|
|||
atomic_compare_exchange_n(obj, expected, desired, true, success, failure)
|
||||
|
||||
#define atomic_flag_test_and_set_n(obj, type) \
|
||||
(sizeof(*(obj)) == 1 ? __atomic_flag_test_and_set_1(obj, type) : \
|
||||
sizeof(*(obj)) == 2 ? __atomic_flag_test_and_set_2(obj, type) : \
|
||||
sizeof(*(obj)) == 4 ? __atomic_flag_test_and_set_4(obj, type) : \
|
||||
__atomic_flag_test_and_set_8(obj, type))
|
||||
(sizeof(*(obj)) == 1 ? nx_atomic_flag_test_and_set_1(obj, type) : \
|
||||
sizeof(*(obj)) == 2 ? nx_atomic_flag_test_and_set_2(obj, type) : \
|
||||
sizeof(*(obj)) == 4 ? nx_atomic_flag_test_and_set_4(obj, type) : \
|
||||
nx_atomic_flag_test_and_set_8(obj, type))
|
||||
|
||||
#define atomic_flag_test_and_set(obj) atomic_flag_test_and_set_n(obj, __ATOMIC_RELAXED)
|
||||
#define atomic_flag_test_and_set_explicit(obj, type) atomic_flag_test_and_set_n(obj, 1, type)
|
||||
|
|
@ -117,46 +117,46 @@
|
|||
#define atomic_flag_clear_explicit(obj, type) atomic_store_explicit(obj, 0, type)
|
||||
|
||||
#define atomic_fetch_and_n(obj, val, type) \
|
||||
(sizeof(*(obj)) == 1 ? __atomic_fetch_and_1(obj, val, type) : \
|
||||
sizeof(*(obj)) == 2 ? __atomic_fetch_and_2(obj, val, type) : \
|
||||
sizeof(*(obj)) == 4 ? __atomic_fetch_and_4(obj, val, type) : \
|
||||
__atomic_fetch_and_8(obj, val, type))
|
||||
(sizeof(*(obj)) == 1 ? nx_atomic_fetch_and_1(obj, val, type) : \
|
||||
sizeof(*(obj)) == 2 ? nx_atomic_fetch_and_2(obj, val, type) : \
|
||||
sizeof(*(obj)) == 4 ? nx_atomic_fetch_and_4(obj, val, type) : \
|
||||
nx_atomic_fetch_and_8(obj, val, type))
|
||||
|
||||
#define atomic_fetch_and(obj, val) atomic_fetch_and_n(obj, val, __ATOMIC_RELAXED)
|
||||
#define atomic_fetch_and_explicit(obj, val, type) atomic_fetch_and_n(obj, val, type)
|
||||
|
||||
#define atomic_fetch_or_n(obj, val, type) \
|
||||
(sizeof(*(obj)) == 1 ? __atomic_fetch_or_1(obj, val, type) : \
|
||||
sizeof(*(obj)) == 2 ? __atomic_fetch_or_2(obj, val, type) : \
|
||||
sizeof(*(obj)) == 4 ? __atomic_fetch_or_4(obj, val, type) : \
|
||||
__atomic_fetch_or_8(obj, val, type))
|
||||
(sizeof(*(obj)) == 1 ? nx_atomic_fetch_or_1(obj, val, type) : \
|
||||
sizeof(*(obj)) == 2 ? nx_atomic_fetch_or_2(obj, val, type) : \
|
||||
sizeof(*(obj)) == 4 ? nx_atomic_fetch_or_4(obj, val, type) : \
|
||||
nx_atomic_fetch_or_8(obj, val, type))
|
||||
|
||||
#define atomic_fetch_or(obj, val) atomic_fetch_or_n(obj, val, __ATOMIC_RELAXED)
|
||||
#define atomic_fetch_or_explicit(obj, val, type) atomic_fetch_or_n(obj, val, type)
|
||||
|
||||
#define atomic_fetch_xor_n(obj, val, type) \
|
||||
(sizeof(*(obj)) == 1 ? __atomic_fetch_xor_1(obj, val, type) : \
|
||||
sizeof(*(obj)) == 2 ? __atomic_fetch_xor_2(obj, val, type) : \
|
||||
sizeof(*(obj)) == 4 ? __atomic_fetch_xor_4(obj, val, type) : \
|
||||
__atomic_fetch_xor_8(obj, val, type))
|
||||
(sizeof(*(obj)) == 1 ? nx_atomic_fetch_xor_1(obj, val, type) : \
|
||||
sizeof(*(obj)) == 2 ? nx_atomic_fetch_xor_2(obj, val, type) : \
|
||||
sizeof(*(obj)) == 4 ? nx_atomic_fetch_xor_4(obj, val, type) : \
|
||||
nx_atomic_fetch_xor_8(obj, val, type))
|
||||
|
||||
#define atomic_fetch_xor(obj, val) atomic_fetch_xor_n(obj, val, __ATOMIC_RELAXED)
|
||||
#define atomic_fetch_xor_explicit(obj, val, type) atomic_fetch_xor_n(obj, val, type)
|
||||
|
||||
#define atomic_fetch_add_n(obj, val, type) \
|
||||
(sizeof(*(obj)) == 1 ? __atomic_fetch_add_1(obj, val, type) : \
|
||||
sizeof(*(obj)) == 2 ? __atomic_fetch_add_2(obj, val, type) : \
|
||||
sizeof(*(obj)) == 4 ? __atomic_fetch_add_4(obj, val, type) : \
|
||||
__atomic_fetch_add_8(obj, val, type))
|
||||
(sizeof(*(obj)) == 1 ? nx_atomic_fetch_add_1(obj, val, type) : \
|
||||
sizeof(*(obj)) == 2 ? nx_atomic_fetch_add_2(obj, val, type) : \
|
||||
sizeof(*(obj)) == 4 ? nx_atomic_fetch_add_4(obj, val, type) : \
|
||||
nx_atomic_fetch_add_8(obj, val, type))
|
||||
|
||||
#define atomic_fetch_add(obj, val) atomic_fetch_add_n(obj, val, __ATOMIC_RELAXED)
|
||||
#define atomic_fetch_add_explicit(obj, val, type) atomic_fetch_add_n(obj, val, type)
|
||||
|
||||
#define atomic_fetch_sub_n(obj, val, type) \
|
||||
(sizeof(*(obj)) == 1 ? __atomic_fetch_sub_1(obj, val, type) : \
|
||||
sizeof(*(obj)) == 2 ? __atomic_fetch_sub_2(obj, val, type) : \
|
||||
sizeof(*(obj)) == 4 ? __atomic_fetch_sub_4(obj, val, type) : \
|
||||
__atomic_fetch_sub_8(obj, val, type))
|
||||
(sizeof(*(obj)) == 1 ? nx_atomic_fetch_sub_1(obj, val, type) : \
|
||||
sizeof(*(obj)) == 2 ? nx_atomic_fetch_sub_2(obj, val, type) : \
|
||||
sizeof(*(obj)) == 4 ? nx_atomic_fetch_sub_4(obj, val, type) : \
|
||||
nx_atomic_fetch_sub_8(obj, val, type))
|
||||
|
||||
#define atomic_fetch_sub(obj, val) atomic_fetch_sub_n(obj, val, __ATOMIC_RELAXED)
|
||||
#define atomic_fetch_sub_explicit(obj, val, type) atomic_fetch_sub_n(obj, val, type)
|
||||
|
|
@ -194,81 +194,85 @@ typedef volatile wchar_t atomic_wchar_t;
|
|||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
void __atomic_store_1(FAR volatile void *ptr, uint8_t value, int memorder);
|
||||
void __atomic_store_2(FAR volatile void *ptr, uint16_t value, int memorder);
|
||||
void __atomic_store_4(FAR volatile void *ptr, uint32_t value, int memorder);
|
||||
void __atomic_store_8(FAR volatile void *ptr, uint64_t value, int memorder);
|
||||
uint8_t __atomic_load_1(FAR const volatile void *ptr, int memorder);
|
||||
uint16_t __atomic_load_2(FAR const volatile void *ptr, int memorder);
|
||||
uint32_t __atomic_load_4(FAR const volatile void *ptr, int memorder);
|
||||
uint64_t __atomic_load_8(FAR const volatile void *ptr, int memorder);
|
||||
uint8_t __atomic_exchange_1(FAR volatile void *ptr, uint8_t value,
|
||||
void nx_atomic_store_1(FAR volatile void *ptr, uint8_t value,
|
||||
int memorder);
|
||||
void nx_atomic_store_2(FAR volatile void *ptr, uint16_t value,
|
||||
int memorder);
|
||||
void nx_atomic_store_4(FAR volatile void *ptr, uint32_t value,
|
||||
int memorder);
|
||||
void nx_atomic_store_8(FAR volatile void *ptr, uint64_t value,
|
||||
int memorder);
|
||||
uint8_t nx_atomic_load_1(FAR const volatile void *ptr, int memorder);
|
||||
uint16_t nx_atomic_load_2(FAR const volatile void *ptr, int memorder);
|
||||
uint32_t nx_atomic_load_4(FAR const volatile void *ptr, int memorder);
|
||||
uint64_t nx_atomic_load_8(FAR const volatile void *ptr, int memorder);
|
||||
uint8_t nx_atomic_exchange_1(FAR volatile void *ptr, uint8_t value,
|
||||
int memorder);
|
||||
uint16_t __atomic_exchange_2(FAR volatile void *ptr, uint16_t value,
|
||||
uint16_t nx_atomic_exchange_2(FAR volatile void *ptr, uint16_t value,
|
||||
int memorder);
|
||||
uint32_t __atomic_exchange_4(FAR volatile void *ptr, uint32_t value,
|
||||
uint32_t nx_atomic_exchange_4(FAR volatile void *ptr, uint32_t value,
|
||||
int memorder);
|
||||
uint64_t __atomic_exchange_8(FAR volatile void *ptr, uint64_t value,
|
||||
uint64_t nx_atomic_exchange_8(FAR volatile void *ptr, uint64_t value,
|
||||
int memorder);
|
||||
bool __atomic_compare_exchange_1(FAR volatile void *mem, FAR void *expect,
|
||||
bool nx_atomic_compare_exchange_1(FAR volatile void *mem, FAR void *expect,
|
||||
uint8_t desired, bool weak, int success,
|
||||
int failure);
|
||||
bool __atomic_compare_exchange_2(FAR volatile void *mem, FAR void *expect,
|
||||
bool nx_atomic_compare_exchange_2(FAR volatile void *mem, FAR void *expect,
|
||||
uint16_t desired, bool weak, int success,
|
||||
int failure);
|
||||
bool __atomic_compare_exchange_4(FAR volatile void *mem, FAR void *expect,
|
||||
bool nx_atomic_compare_exchange_4(FAR volatile void *mem, FAR void *expect,
|
||||
uint32_t desired, bool weak, int success,
|
||||
int failure);
|
||||
bool __atomic_compare_exchange_8(FAR volatile void *mem, FAR void *expect,
|
||||
bool nx_atomic_compare_exchange_8(FAR volatile void *mem, FAR void *expect,
|
||||
uint64_t desired, bool weak, int success,
|
||||
int failure);
|
||||
uint8_t __atomic_flag_test_and_set_1(FAR const volatile void *ptr,
|
||||
uint8_t nx_atomic_flag_test_and_set_1(FAR const volatile void *ptr,
|
||||
int memorder);
|
||||
uint16_t __atomic_flag_test_and_set_2(FAR const volatile void *ptr,
|
||||
uint16_t nx_atomic_flag_test_and_set_2(FAR const volatile void *ptr,
|
||||
int memorder);
|
||||
uint32_t __atomic_flag_test_and_set_4(FAR const volatile void *ptr,
|
||||
uint32_t nx_atomic_flag_test_and_set_4(FAR const volatile void *ptr,
|
||||
int memorder);
|
||||
uint64_t __atomic_flag_test_and_set_8(FAR const volatile void *ptr,
|
||||
uint64_t nx_atomic_flag_test_and_set_8(FAR const volatile void *ptr,
|
||||
int memorder);
|
||||
uint8_t __atomic_fetch_add_1(FAR volatile void *ptr, uint8_t value,
|
||||
uint8_t nx_atomic_fetch_add_1(FAR volatile void *ptr, uint8_t value,
|
||||
int memorder);
|
||||
uint16_t __atomic_fetch_add_2(FAR volatile void *ptr, uint16_t value,
|
||||
uint16_t nx_atomic_fetch_add_2(FAR volatile void *ptr, uint16_t value,
|
||||
int memorder);
|
||||
uint32_t __atomic_fetch_add_4(FAR volatile void *ptr, uint32_t value,
|
||||
uint32_t nx_atomic_fetch_add_4(FAR volatile void *ptr, uint32_t value,
|
||||
int memorder);
|
||||
uint64_t __atomic_fetch_add_8(FAR volatile void *ptr, uint64_t value,
|
||||
uint64_t nx_atomic_fetch_add_8(FAR volatile void *ptr, uint64_t value,
|
||||
int memorder);
|
||||
uint8_t __atomic_fetch_sub_1(FAR volatile void *ptr, uint8_t value,
|
||||
uint8_t nx_atomic_fetch_sub_1(FAR volatile void *ptr, uint8_t value,
|
||||
int memorder);
|
||||
uint16_t __atomic_fetch_sub_2(FAR volatile void *ptr, uint16_t value,
|
||||
uint16_t nx_atomic_fetch_sub_2(FAR volatile void *ptr, uint16_t value,
|
||||
int memorder);
|
||||
uint32_t __atomic_fetch_sub_4(FAR volatile void *ptr, uint32_t value,
|
||||
uint32_t nx_atomic_fetch_sub_4(FAR volatile void *ptr, uint32_t value,
|
||||
int memorder);
|
||||
uint64_t __atomic_fetch_sub_8(FAR volatile void *ptr, uint64_t value,
|
||||
uint64_t nx_atomic_fetch_sub_8(FAR volatile void *ptr, uint64_t value,
|
||||
int memorder);
|
||||
uint8_t __atomic_fetch_and_1(FAR volatile void *ptr, uint8_t value,
|
||||
uint8_t nx_atomic_fetch_and_1(FAR volatile void *ptr, uint8_t value,
|
||||
int memorder);
|
||||
uint16_t __atomic_fetch_and_2(FAR volatile void *ptr, uint16_t value,
|
||||
uint16_t nx_atomic_fetch_and_2(FAR volatile void *ptr, uint16_t value,
|
||||
int memorder);
|
||||
uint32_t __atomic_fetch_and_4(FAR volatile void *ptr, uint32_t value,
|
||||
uint32_t nx_atomic_fetch_and_4(FAR volatile void *ptr, uint32_t value,
|
||||
int memorder);
|
||||
uint64_t __atomic_fetch_and_8(FAR volatile void *ptr, uint64_t value,
|
||||
uint64_t nx_atomic_fetch_and_8(FAR volatile void *ptr, uint64_t value,
|
||||
int memorder);
|
||||
uint8_t __atomic_fetch_or_1(FAR volatile void *ptr, uint8_t value,
|
||||
uint8_t nx_atomic_fetch_or_1(FAR volatile void *ptr, uint8_t value,
|
||||
int memorder);
|
||||
uint16_t __atomic_fetch_or_2(FAR volatile void *ptr, uint16_t value,
|
||||
uint16_t nx_atomic_fetch_or_2(FAR volatile void *ptr, uint16_t value,
|
||||
int memorder);
|
||||
uint32_t __atomic_fetch_or_4(FAR volatile void *ptr, uint32_t value,
|
||||
uint32_t nx_atomic_fetch_or_4(FAR volatile void *ptr, uint32_t value,
|
||||
int memorder);
|
||||
uint64_t __atomic_fetch_or_8(FAR volatile void *ptr, uint64_t value,
|
||||
uint64_t nx_atomic_fetch_or_8(FAR volatile void *ptr, uint64_t value,
|
||||
int memorder);
|
||||
uint8_t __atomic_fetch_xor_1(FAR volatile void *ptr, uint8_t value,
|
||||
uint8_t nx_atomic_fetch_xor_1(FAR volatile void *ptr, uint8_t value,
|
||||
int memorder);
|
||||
uint16_t __atomic_fetch_xor_2(FAR volatile void *ptr, uint16_t value,
|
||||
uint16_t nx_atomic_fetch_xor_2(FAR volatile void *ptr, uint16_t value,
|
||||
int memorder);
|
||||
uint32_t __atomic_fetch_xor_4(FAR volatile void *ptr, uint32_t value,
|
||||
uint32_t nx_atomic_fetch_xor_4(FAR volatile void *ptr, uint32_t value,
|
||||
int memorder);
|
||||
uint64_t __atomic_fetch_xor_8(FAR volatile void *ptr, uint64_t value,
|
||||
uint64_t nx_atomic_fetch_xor_8(FAR volatile void *ptr, uint64_t value,
|
||||
int memorder);
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_LIB_STDATOMIC_H */
|
||||
|
|
|
|||
|
|
@ -141,5 +141,9 @@
|
|||
#define STRINGIFY_(x) #x
|
||||
#define STRINGIFY(x) STRINGIFY_(x)
|
||||
|
||||
/* Concatenate the arguments */
|
||||
|
||||
#define CONCATENATE(a, b) a##b
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_MACRO_H */
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,14 @@
|
|||
|
||||
menu "Architecture-Specific Support"
|
||||
|
||||
config LIBC_ARCH_ATOMIC
|
||||
bool "arch_atomic"
|
||||
default n
|
||||
---help---
|
||||
If this configuration is selected and <include/nuttx/atomic.h> is
|
||||
included, arch_atomic.c will be linked instead of built-in
|
||||
atomic function.
|
||||
|
||||
config ARCH_LOWPUTC
|
||||
bool "Low-level console output"
|
||||
default y
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue