diff --git a/doc/guides/porting/arch.rst b/doc/guides/porting/arch.rst index 6002c00dbd7..a2915061287 100644 --- a/doc/guides/porting/arch.rst +++ b/doc/guides/porting/arch.rst @@ -412,6 +412,10 @@ expected to be implemented as part of an architecture port. * Atomic operators. + * If instructions do exist for a given architecture, the implementation is + configured using the :option:`CONFIG_ATOMIC_OPERATIONS_ARCH` Kconfig + option. + * If instructions do not exist for a given architecture, a generic version that wraps :c:func:`irq_lock` or :c:func:`irq_unlock` around non-atomic operations exists. It is configured using the diff --git a/include/sys/atomic.h b/include/sys/atomic.h index 774e5042afd..249d0cb924f 100644 --- a/include/sys/atomic.h +++ b/include/sys/atomic.h @@ -33,7 +33,10 @@ typedef atomic_ptr_t atomic_ptr_val_t; # ifdef CONFIG_XTENSA /* Not all Xtensa toolchains support GCC-style atomic intrinsics */ # include -# endif +# else +/* Other arch specific implementation */ +# include +# endif /* CONFIG_XTENSA */ #else /* Default. See this file for the Doxygen reference: */ #include diff --git a/include/sys/atomic_arch.h b/include/sys/atomic_arch.h new file mode 100644 index 00000000000..fad339bf933 --- /dev/null +++ b/include/sys/atomic_arch.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 Demant A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_SYS_ATOMIC_ARCH_H_ +#define ZEPHYR_INCLUDE_SYS_ATOMIC_ARCH_H_ + +/* Included from */ + +/* Arch specific atomic primitives */ + +extern bool atomic_cas(atomic_t *target, atomic_val_t old_value, + atomic_val_t new_value); + +extern bool atomic_ptr_cas(atomic_ptr_t *target, void *old_value, + void *new_value); + +extern atomic_val_t atomic_add(atomic_t *target, atomic_val_t value); + +extern atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value); + +extern atomic_val_t atomic_inc(atomic_t *target); + +extern atomic_val_t atomic_dec(atomic_t *target); + +extern atomic_val_t atomic_get(const atomic_t *target); + +extern void *atomic_ptr_get(const atomic_ptr_t *target); + +extern atomic_val_t atomic_set(atomic_t *target, atomic_val_t value); + +extern void *atomic_ptr_set(atomic_ptr_t *target, void *value); + +extern atomic_val_t atomic_clear(atomic_t *target); + +extern void *atomic_ptr_clear(atomic_ptr_t *target); + +extern atomic_val_t atomic_or(atomic_t *target, atomic_val_t value); + +extern atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value); + +extern atomic_val_t atomic_and(atomic_t *target, atomic_val_t value); + +extern atomic_val_t atomic_nand(atomic_t *target, atomic_val_t value); + + +#endif /* ZEPHYR_INCLUDE_SYS_ATOMIC_ARCH_H_ */