From 74a942e6738ba7b6549842d760110c95681a0e1c Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Mon, 1 May 2023 14:33:31 +0200 Subject: [PATCH] barriers: Introduce barrier operations Introduce a new API for barrier operations starting with a general skeleton and the implementation for barrier_data_memory_fence_full(). Select a built-in or an arch-based implementation according to new Kconfig symbols CONFIG_BARRIER_OPERATIONS_BUILTIN and CONFIG_BARRIER_OPERATIONS_ARCH. The built-in implementation falls back on the compiler built-in function using __ATOMIC_SEQ_CST as it is done for the atomic APIs already. Signed-off-by: Carlo Caione --- include/zephyr/sys/barrier.h | 47 ++++++++++++++++++++++++++++ include/zephyr/sys/barrier_builtin.h | 29 +++++++++++++++++ kernel/Kconfig | 15 +++++++++ 3 files changed, 91 insertions(+) create mode 100644 include/zephyr/sys/barrier.h create mode 100644 include/zephyr/sys/barrier_builtin.h diff --git a/include/zephyr/sys/barrier.h b/include/zephyr/sys/barrier.h new file mode 100644 index 00000000000..6acc0476ec1 --- /dev/null +++ b/include/zephyr/sys/barrier.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_SYS_BARRIER_H_ +#define ZEPHYR_INCLUDE_SYS_BARRIER_H_ + +#include + +#if defined(CONFIG_BARRIER_OPERATIONS_ARCH) +/* Empty */ +#elif defined(CONFIG_BARRIER_OPERATIONS_BUILTIN) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup barrier_apis Barrier Services APIs + * @ingroup kernel_apis + * @{ + */ + +/** + * @brief Full/sequentially-consistent data memory barrier. + * + * This routine acts as a synchronization fence between threads and prevents + * re-ordering of data accesses instructions across the barrier instruction. + */ +static ALWAYS_INLINE void barrier_dmem_fence_full(void) +{ +#if defined(CONFIG_BARRIER_OPERATIONS_ARCH) || defined(CONFIG_BARRIER_OPERATIONS_BUILTIN) + z_barrier_dmem_fence_full(); +#endif +} + +/** @} */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ZEPHYR_INCLUDE_SYS_ATOMIC_H_ */ diff --git a/include/zephyr/sys/barrier_builtin.h b/include/zephyr/sys/barrier_builtin.h new file mode 100644 index 00000000000..98bec6eaa36 --- /dev/null +++ b/include/zephyr/sys/barrier_builtin.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_SYS_BARRIER_BUILTIN_H_ +#define ZEPHYR_INCLUDE_SYS_BARRIER_BUILTIN_H_ + +#ifndef ZEPHYR_INCLUDE_SYS_BARRIER_H_ +#error Please include +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static ALWAYS_INLINE void z_barrier_dmem_fence_full(void) +{ + __atomic_thread_fence(__ATOMIC_SEQ_CST); +} + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_SYS_BARRIER_BUILTIN_H_ */ diff --git a/kernel/Kconfig b/kernel/Kconfig index 4dceaaf662e..6dbca69694f 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -452,6 +452,21 @@ config SYSTEM_WORKQUEUE_NO_YIELD endmenu +menu "Barrier Operations" +config BARRIER_OPERATIONS_BUILTIN + bool + help + Use the compiler builtin functions for barrier operations. This is + the preferred method. However, support for all arches in GCC is + incomplete. + +config BARRIER_OPERATIONS_ARCH + bool + help + Use when there isn't support for compiler built-ins, but you have + written optimized assembly code under arch/ which implements these. +endmenu + menu "Atomic Operations" config ATOMIC_OPERATIONS_BUILTIN bool