From c14be62c4c2195661888a7321d8cc255b0b0dab3 Mon Sep 17 00:00:00 2001 From: zhangyu117 Date: Fri, 22 Aug 2025 11:32:56 +0800 Subject: [PATCH 01/14] nuttx/libc: arch_atomic.c uses IRQ switching, no SMP support The atomic implementation of machine/arch_atomic.c is achieved by switching interrupts. This version does not support SMP. Signed-off-by: zhangyu117 --- libs/libc/machine/arch_atomic.c | 78 +++++++++++++++------------------ 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/libs/libc/machine/arch_atomic.c b/libs/libc/machine/arch_atomic.c index 87d68008d5e03..12ff71f4b46c1 100644 --- a/libs/libc/machine/arch_atomic.c +++ b/libs/libc/machine/arch_atomic.c @@ -31,12 +31,6 @@ #include #include -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static spinlock_t g_atomic_lock = SP_UNLOCKED; - /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -46,11 +40,11 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; void weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ type value, int memorder) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ \ *(FAR type *)ptr = value; \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ } #define LOAD(fn, n, type) \ @@ -58,11 +52,11 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type weak_function CONCATENATE(fn, n)(FAR const volatile void *ptr, \ int memorder) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ \ type ret = *(FAR type *)ptr; \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return ret; \ } @@ -71,13 +65,13 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ type value, int memorder) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ FAR type *tmp = (FAR type *)ptr; \ \ type ret = *tmp; \ *tmp = value; \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return ret; \ } @@ -89,7 +83,7 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; int success, int failure) \ { \ bool ret = false; \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ FAR type *tmpmem = (FAR type *)mem; \ FAR type *tmpexp = (FAR type *)expect; \ \ @@ -103,7 +97,7 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; *tmpexp = *tmpmem; \ } \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return ret; \ } @@ -112,13 +106,13 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ int memorder) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ FAR type *tmp = (FAR type *)ptr; \ type ret = *tmp; \ \ *(FAR type *)ptr = 1; \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return ret; \ } @@ -127,13 +121,13 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ type value, int memorder) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ FAR type *tmp = (FAR type *)ptr; \ type ret = *tmp; \ \ *tmp = *tmp + value; \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return ret; \ } @@ -142,13 +136,13 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ type value, int memorder) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ FAR type *tmp = (FAR type *)ptr; \ type ret = *tmp; \ \ *tmp = *tmp - value; \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return ret; \ } @@ -157,13 +151,13 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ type value, int memorder) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ FAR type *tmp = (FAR type *)ptr; \ type ret = *tmp; \ \ *tmp = *tmp & value; \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return ret; \ } @@ -172,13 +166,13 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ type value, int memorder) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ FAR type *tmp = (FAR type *)ptr; \ type ret = *tmp; \ \ *tmp = *tmp | value; \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return ret; \ } @@ -187,13 +181,13 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ type value, int memorder) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ FAR type *tmp = (FAR type *)ptr; \ type ret = *tmp; \ \ *tmp = *tmp ^ value; \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return ret; \ } @@ -202,12 +196,12 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ type value) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ FAR type *tmp = (FAR type *)ptr; \ \ *tmp = *tmp + value; \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return *tmp; \ } @@ -216,12 +210,12 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ type value) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ FAR type *tmp = (FAR type *)ptr; \ \ *tmp = *tmp - value; \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return *tmp; \ } @@ -230,12 +224,12 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ type value) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ FAR type *tmp = (FAR type *)ptr; \ \ *tmp = *tmp | value; \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return *tmp; \ } @@ -244,12 +238,12 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ type value) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ FAR type *tmp = (FAR type *)ptr; \ \ *tmp = *tmp & value; \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return *tmp; \ } @@ -258,12 +252,12 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ type value) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ FAR type *tmp = (FAR type *)ptr; \ \ *tmp = *tmp ^ value; \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return *tmp; \ } @@ -272,12 +266,12 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ type value) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ FAR type *tmp = (FAR type *)ptr; \ \ *tmp = ~(*tmp & value); \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return *tmp; \ } @@ -288,7 +282,7 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type newvalue) \ { \ bool ret = false; \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ FAR type *tmp = (FAR type *)ptr; \ \ if (*tmp == oldvalue) \ @@ -297,7 +291,7 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; *tmp = newvalue; \ } \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return ret; \ } @@ -307,7 +301,7 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type oldvalue, \ type newvalue) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = up_irq_save(); \ FAR type *tmp = (FAR type *)ptr; \ type ret = *tmp; \ \ @@ -316,7 +310,7 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; *tmp = newvalue; \ } \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + up_irq_restore(irqstate); \ return ret; \ } From f00fd9f9f9df5f7e60b3bb58e331ad21c3c2006b Mon Sep 17 00:00:00 2001 From: zhangyu117 Date: Fri, 14 Aug 2026 16:01:47 +0800 Subject: [PATCH 02/14] arch/tricore: add arch atomic function Tricore gcc does not support atomic interface but some users need to use atomic operations, so support atomic function using tricore arch instructions (__cmpAndSwap/__swap/__ld32). Signed-off-by: zhangyu117 --- libs/libc/machine/tricore/CMakeLists.txt | 1 + libs/libc/machine/tricore/Make.defs | 1 + libs/libc/machine/tricore/arch_atomic.c | 231 +++++++++++++++++++++++ 3 files changed, 233 insertions(+) create mode 100644 libs/libc/machine/tricore/arch_atomic.c diff --git a/libs/libc/machine/tricore/CMakeLists.txt b/libs/libc/machine/tricore/CMakeLists.txt index e2708f1e04bea..b8d393cde8e93 100644 --- a/libs/libc/machine/tricore/CMakeLists.txt +++ b/libs/libc/machine/tricore/CMakeLists.txt @@ -22,6 +22,7 @@ set(SRCS) +list(APPEND SRCS arch_atomic.c) if(CONFIG_ARCH_SETJMP_H) list(APPEND SRCS arch_setjmp.c) endif() diff --git a/libs/libc/machine/tricore/Make.defs b/libs/libc/machine/tricore/Make.defs index 118afa1ccbe61..c0dc5542ce0b2 100644 --- a/libs/libc/machine/tricore/Make.defs +++ b/libs/libc/machine/tricore/Make.defs @@ -20,6 +20,7 @@ # ############################################################################ +CSRCS += arch_atomic.c ifeq ($(CONFIG_ARCH_SETJMP_H),y) CSRCS += arch_setjmp.c endif diff --git a/libs/libc/machine/tricore/arch_atomic.c b/libs/libc/machine/tricore/arch_atomic.c new file mode 100644 index 0000000000000..7f10fa0f07902 --- /dev/null +++ b/libs/libc/machine/tricore/arch_atomic.c @@ -0,0 +1,231 @@ +/**************************************************************************** + * libs/libc/machine/tricore/arch_atomic.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ARCH_ATOMIC_STORE_4(func) \ + \ + void func(volatile void *ptr, int32_t value, int memorder) \ + { \ + __swap((void *)ptr, value); \ + } + +#define ARCH_ATOMIC_LOAD_4(func) \ + \ + int32_t func(const volatile void *ptr, int memorder) \ + { \ + return __ld32((void *)ptr); \ + } + +#define ARCH_ATOMIC_EXCHANGE_4(func) \ + \ + int32_t func(volatile void *ptr, int32_t value, int memorder) \ + { \ + return __swap((void *)ptr, value); \ + } + +#define ARCH_ATOMIC_COMPARE_EXCHANGE_4(func) \ + \ + bool func(volatile void *ptr, void *expect, int32_t desired, \ + bool weak, int success, int failure) \ + { \ + int32_t old; \ + \ + old = __cmpAndSwap(ptr, desired, *(int32_t *)expect); \ + if (old == *(int32_t *)expect) \ + { \ + return true; \ + } \ + \ + *(int32_t *)expect = old; \ + \ + return false; \ + } + +#define ARCH_ATOMIC_FLAGS_TEST_AND_SET_4(func) \ + \ + int32_t func(volatile void *ptr, int memorder) \ + { \ + return __swap((void *)ptr, 1); \ + } + +#define ARCH_ATOMIC_FETCH_ADD_4(func) \ + \ + int32_t func(volatile void *ptr, int32_t value, int memorder) \ + \ + { \ + int32_t old_val; \ + \ + do \ + { \ + old_val = nx_atomic_load_4(ptr, memorder); \ + } \ + while (__cmpAndSwap(ptr, old_val + value, old_val) != old_val); \ + \ + return old_val; \ + } + +#define ARCH_ATOMIC_FETCH_SUB_4(func) \ + \ + int32_t func(volatile void *ptr, int32_t value, int memorder) \ + { \ + int32_t old_val; \ + \ + do \ + { \ + old_val = nx_atomic_load_4(ptr, memorder); \ + } \ + while (__cmpAndSwap(ptr, old_val - value, old_val) != old_val); \ + \ + return old_val; \ + } + +#define ARCH_ATOMIC_FETCH_AND_4(func) \ + \ + int32_t func(volatile void *ptr, int32_t value, int memorder) \ + { \ + int32_t old_val; \ + \ + do \ + { \ + old_val = nx_atomic_load_4(ptr, memorder); \ + } \ + while (__cmpAndSwap(ptr, old_val & value, old_val) != old_val); \ + \ + return old_val; \ + } + +#define ARCH_ATOMIC_FETCH_OR_4(func) \ + \ + int32_t func(volatile void *ptr, int32_t value, int memorder) \ + { \ + int32_t old_val; \ + \ + do \ + { \ + old_val = nx_atomic_load_4(ptr, memorder); \ + } \ + while (__cmpAndSwap(ptr, old_val | value, old_val) != old_val); \ + \ + return old_val; \ + } + +#define ARCH_ATOMIC_FETCH_XOR_4(func) \ + \ + int32_t func(volatile void *ptr, int32_t value, int memorder) \ + { \ + int32_t old_val; \ + \ + do \ + { \ + old_val = nx_atomic_load_4(ptr, memorder); \ + } \ + while (__cmpAndSwap(ptr, old_val ^ value, old_val) != old_val); \ + \ + return old_val; \ + } + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: atomic_store_4 + ****************************************************************************/ + +ARCH_ATOMIC_STORE_4(__atomic_store_4) +ARCH_ATOMIC_STORE_4(nx_atomic_store_4) + +/**************************************************************************** + * Name: atomic_load_4 + ****************************************************************************/ + +ARCH_ATOMIC_LOAD_4(__atomic_load_4) +ARCH_ATOMIC_LOAD_4(nx_atomic_load_4) + +/**************************************************************************** + * Name: atomic_exchange_4 + ****************************************************************************/ + +ARCH_ATOMIC_EXCHANGE_4(__atomic_exchange_4) +ARCH_ATOMIC_EXCHANGE_4(nx_atomic_exchange_4) + +/**************************************************************************** + * Name: atomic_compare_exchange_4 + ****************************************************************************/ + +ARCH_ATOMIC_COMPARE_EXCHANGE_4(__atomic_compare_exchange_4) +ARCH_ATOMIC_COMPARE_EXCHANGE_4(nx_atomic_compare_exchange_4) + +/**************************************************************************** + * Name: atomic_flag_test_and_set_4 + ****************************************************************************/ + +ARCH_ATOMIC_FLAGS_TEST_AND_SET_4(__atomic_flags_test_and_set_4) +ARCH_ATOMIC_FLAGS_TEST_AND_SET_4(nx_atomic_flags_test_and_set_4) + +/**************************************************************************** + * Name: atomic_fetch_add_4 + ****************************************************************************/ + +ARCH_ATOMIC_FETCH_ADD_4(__atomic_fetch_add_4) +ARCH_ATOMIC_FETCH_ADD_4(nx_atomic_fetch_add_4) + +/**************************************************************************** + * Name: atomic_fetch_sub_4 + ****************************************************************************/ + +ARCH_ATOMIC_FETCH_SUB_4(__atomic_fetch_sub_4) +ARCH_ATOMIC_FETCH_SUB_4(nx_atomic_fetch_sub_4) + +/**************************************************************************** + * Name: atomic_fetch_and_4 + ****************************************************************************/ + +ARCH_ATOMIC_FETCH_AND_4(__atomic_fetch_and_4) +ARCH_ATOMIC_FETCH_AND_4(nx_atomic_fetch_and_4) + +/**************************************************************************** + * Name: atomic_fetch_or_4 + ****************************************************************************/ + +ARCH_ATOMIC_FETCH_OR_4(__atomic_fetch_or_4) +ARCH_ATOMIC_FETCH_OR_4(nx_atomic_fetch_or_4) + +/**************************************************************************** + * Name: atomic_fetch_xor_4 + ****************************************************************************/ + +ARCH_ATOMIC_FETCH_XOR_4(__atomic_fetch_xor_4) +ARCH_ATOMIC_FETCH_XOR_4(nx_atomic_fetch_xor_4) From 1c538038b5ff78a754fdec0bd93c5f950177ab5e Mon Sep 17 00:00:00 2001 From: zhangyu117 Date: Thu, 13 Aug 2026 22:32:10 +0800 Subject: [PATCH 03/14] nuttx/libc: refine the atomic related Kconfig Refine the atomic Kconfig to support multiple backends: LIBC_ATOMIC_TOOLCHAIN (compiler builtins), LIBC_ATOMIC_ARCH (arch instructions), and LIBC_ATOMIC_IRQ (interrupt disable). Rename arch_atomic.c to arch_atomic_irq.c since it supports the IRQ backend. Signed-off-by: zhangyu117 --- arch/arm/Kconfig | 4 +--- arch/renesas/Kconfig | 1 + arch/risc-v/Kconfig | 1 + arch/xtensa/src/esp32/Kconfig | 2 +- .../arm/am67/t3-gem-o1/configs/nsh/defconfig | 1 - include/nuttx/atomic.h | 2 +- libs/libc/machine/CMakeLists.txt | 2 +- libs/libc/machine/Kconfig | 21 ++++++++++++++----- libs/libc/machine/Make.defs | 2 +- .../{arch_atomic.c => arch_atomic_irq.c} | 4 ++-- libs/libc/machine/tricore/CMakeLists.txt | 5 ++++- libs/libc/machine/tricore/Make.defs | 3 +++ 12 files changed, 32 insertions(+), 16 deletions(-) rename libs/libc/machine/{arch_atomic.c => arch_atomic_irq.c} (99%) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index bf62351cbb4ef..15b36b1cb13cb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -843,7 +843,6 @@ config ARCH_CHIP_CXD56XX select ARCH_HAVE_MATH_H select ARCH_HAVE_I2CRESET select ARCH_HAVE_CUSTOM_TESTSET - select LIBC_ARCH_ATOMIC if SMP ---help--- Sony CXD56XX (ARM Cortex-M4) architectures @@ -935,7 +934,7 @@ config ARCH_CHIP_CXD32XX bool "Sony CXD32xx" select ARCH_CORTEXM4 select ARCH_HAVE_FPU - select LIBC_ARCH_ATOMIC + select LIBC_ATOMIC_IRQ ---help--- Sony CXD32XX (ARM Cortex-M4) architectures @@ -943,7 +942,6 @@ config ARCH_CHIP_HT32F491X3 bool "Holtek HT32F491x3" select ARCH_CORTEXM4 select ARCH_HAVE_FPU - select LIBC_ARCH_ATOMIC ---help--- Holtek HT32F491x3 (ARM Cortex-M4) architectures diff --git a/arch/renesas/Kconfig b/arch/renesas/Kconfig index d89cc1ead7ab2..543c084494fe0 100644 --- a/arch/renesas/Kconfig +++ b/arch/renesas/Kconfig @@ -62,6 +62,7 @@ config ARCH_RENESAS_RX default n select ARCH_HAVE_SETJMP select CYGWIN_WINTOOL if WINDOWS_CYGWIN + select LIBC_ATOMIC_IRQ config ARCH_RX65N bool diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index 6ce72af7af77b..dabc4d902a55f 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -82,6 +82,7 @@ config ARCH_CHIP_BL602 select ONESHOT_COUNT select ONESHOT_FAST_DIVISION select ALARM_ARCH + select LIBC_ATOMIC_IRQ ---help--- BouffaloLab BL602(rv32imfc) diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig index 3836f0ac6bb2c..4084d7e346b8f 100644 --- a/arch/xtensa/src/esp32/Kconfig +++ b/arch/xtensa/src/esp32/Kconfig @@ -893,7 +893,7 @@ config ESP32_RTC_HEAP config ESP32_IRAM_HEAP bool "Use the rest of IRAM as a separate heap" select ARCH_HAVE_EXTRA_HEAPS - select LIBC_ARCH_ATOMIC + select LIBC_ATOMIC_IRQ select ARCH_USE_TEXT_HEAP default n diff --git a/boards/arm/am67/t3-gem-o1/configs/nsh/defconfig b/boards/arm/am67/t3-gem-o1/configs/nsh/defconfig index afe0185a0e0aa..3bf01e873140d 100644 --- a/boards/arm/am67/t3-gem-o1/configs/nsh/defconfig +++ b/boards/arm/am67/t3-gem-o1/configs/nsh/defconfig @@ -30,7 +30,6 @@ CONFIG_FS_PROCFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_INIT_ENTRYPOINT="nsh_main" -CONFIG_LIBC_ARCH_ATOMIC=y CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_FILEIOSIZE=512 CONFIG_NSH_READLINE=y diff --git a/include/nuttx/atomic.h b/include/nuttx/atomic.h index 02fb266a42886..d2ea13d9e446b 100644 --- a/include/nuttx/atomic.h +++ b/include/nuttx/atomic.h @@ -36,7 +36,7 @@ # endif #endif -#if !defined(CONFIG_LIBC_ARCH_ATOMIC) +#if defined(CONFIG_LIBC_ATOMIC_TOOLCHAIN) # if __has_include() && defined(__cplusplus) extern "C++" { diff --git a/libs/libc/machine/CMakeLists.txt b/libs/libc/machine/CMakeLists.txt index 5f4869dc7d6c0..c31234ee04865 100644 --- a/libs/libc/machine/CMakeLists.txt +++ b/libs/libc/machine/CMakeLists.txt @@ -22,7 +22,7 @@ add_subdirectory(${CONFIG_ARCH}) -target_sources(c PRIVATE arch_atomic.c) +target_sources(c PRIVATE arch_atomic_irq.c) if(CONFIG_MM_KASAN) target_sources(c PRIVATE arch_libc.c) diff --git a/libs/libc/machine/Kconfig b/libs/libc/machine/Kconfig index f89a42159f9e0..e07b9790c3bfd 100644 --- a/libs/libc/machine/Kconfig +++ b/libs/libc/machine/Kconfig @@ -9,13 +9,24 @@ menu "Architecture-Specific Support" -config LIBC_ARCH_ATOMIC - bool "arch_atomic" +config LIBC_ATOMIC_IRQ + bool + default n + ---help--- + atomic function by irq disable/enable + +config LIBC_ATOMIC_ARCH + bool + default n + ---help--- + arch_atomic by arch instruction + +config LIBC_ATOMIC_TOOLCHAIN + bool + default y if !LIBC_ATOMIC_IRQ && !LIBC_ATOMIC_ARCH default n ---help--- - If this configuration is selected and is - included, arch_atomic.c will be linked instead of built-in - atomic function. + atomic function from toolchain config ARCH_LOWPUTC bool "Low-level console output" diff --git a/libs/libc/machine/Make.defs b/libs/libc/machine/Make.defs index 73e34fecccba8..149df32df17f4 100644 --- a/libs/libc/machine/Make.defs +++ b/libs/libc/machine/Make.defs @@ -20,7 +20,7 @@ # ############################################################################ -CSRCS += arch_atomic.c +CSRCS += arch_atomic_irq.c ifeq ($(CONFIG_MM_KASAN),y) CSRCS += arch_libc.c diff --git a/libs/libc/machine/arch_atomic.c b/libs/libc/machine/arch_atomic_irq.c similarity index 99% rename from libs/libc/machine/arch_atomic.c rename to libs/libc/machine/arch_atomic_irq.c index 12ff71f4b46c1..98c0aae5a1cab 100644 --- a/libs/libc/machine/arch_atomic.c +++ b/libs/libc/machine/arch_atomic_irq.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libs/libc/machine/arch_atomic.c + * libs/libc/machine/arch_atomic_irq.c * * SPDX-License-Identifier: Apache-2.0 * @@ -78,7 +78,7 @@ #define CMP_EXCHANGE(fn, n, type) \ \ bool weak_function CONCATENATE(fn, n)(FAR volatile void *mem, \ - FAR void *expect, \ + FAR volatile void *expect, \ type desired, bool weak, \ int success, int failure) \ { \ diff --git a/libs/libc/machine/tricore/CMakeLists.txt b/libs/libc/machine/tricore/CMakeLists.txt index b8d393cde8e93..689da31505c6b 100644 --- a/libs/libc/machine/tricore/CMakeLists.txt +++ b/libs/libc/machine/tricore/CMakeLists.txt @@ -22,7 +22,10 @@ set(SRCS) -list(APPEND SRCS arch_atomic.c) +if(CONFIG_LIBC_ATOMIC_ARCH) + list(APPEND SRCS arch_atomic.c) +endif() + if(CONFIG_ARCH_SETJMP_H) list(APPEND SRCS arch_setjmp.c) endif() diff --git a/libs/libc/machine/tricore/Make.defs b/libs/libc/machine/tricore/Make.defs index c0dc5542ce0b2..b39fa5ac414bb 100644 --- a/libs/libc/machine/tricore/Make.defs +++ b/libs/libc/machine/tricore/Make.defs @@ -20,7 +20,10 @@ # ############################################################################ +ifeq ($(CONFIG_LIBC_ATOMIC_ARCH),y) CSRCS += arch_atomic.c +endif + ifeq ($(CONFIG_ARCH_SETJMP_H),y) CSRCS += arch_setjmp.c endif From f3f779b1ab9f3ba011aa5435c29dd8ad608afcb5 Mon Sep 17 00:00:00 2001 From: zhangyu117 Date: Fri, 21 Aug 2026 10:58:23 +0800 Subject: [PATCH 04/14] libc/machine: split atomic into header, arch_atomic_irq.c, arch_atomic64.c Split the atomic implementation into three files: - arch_atomic.h: Shared macros (STORE, LOAD, etc.) using atomic_lock()/ atomic_unlock() abstraction - arch_atomic_irq.c: 32-bit atomic functions using IRQ disable (conditional on CONFIG_LIBC_ATOMIC_IRQ via Make.defs) - arch_atomic64.c: 64-bit atomic functions using spinlock (always compiled, multi-core safe). The __atomic_* functions are always provided (GCC runtime helpers), while nx_atomic_* functions are conditional on !CONFIG_LIBC_ATOMIC_TOOLCHAIN. Signed-off-by: zhangyu117 --- libs/libc/machine/CMakeLists.txt | 6 +- libs/libc/machine/Make.defs | 6 +- libs/libc/machine/arch_atomic.h | 320 +++++++++++++++++++++ libs/libc/machine/arch_atomic64.c | 201 +++++++++++++ libs/libc/machine/arch_atomic_irq.c | 423 ++-------------------------- 5 files changed, 550 insertions(+), 406 deletions(-) create mode 100644 libs/libc/machine/arch_atomic.h create mode 100644 libs/libc/machine/arch_atomic64.c diff --git a/libs/libc/machine/CMakeLists.txt b/libs/libc/machine/CMakeLists.txt index c31234ee04865..148039dec6c7a 100644 --- a/libs/libc/machine/CMakeLists.txt +++ b/libs/libc/machine/CMakeLists.txt @@ -22,7 +22,11 @@ add_subdirectory(${CONFIG_ARCH}) -target_sources(c PRIVATE arch_atomic_irq.c) +if(CONFIG_LIBC_ATOMIC_IRQ) + target_sources(c PRIVATE arch_atomic_irq.c) +endif() + +target_sources(c PRIVATE arch_atomic64.c) if(CONFIG_MM_KASAN) target_sources(c PRIVATE arch_libc.c) diff --git a/libs/libc/machine/Make.defs b/libs/libc/machine/Make.defs index 149df32df17f4..5821f401ef737 100644 --- a/libs/libc/machine/Make.defs +++ b/libs/libc/machine/Make.defs @@ -20,7 +20,11 @@ # ############################################################################ -CSRCS += arch_atomic_irq.c +ifeq ($(CONFIG_LIBC_ATOMIC_IRQ),y) + CSRCS += arch_atomic_irq.c +endif + +CSRCS += arch_atomic64.c ifeq ($(CONFIG_MM_KASAN),y) CSRCS += arch_libc.c diff --git a/libs/libc/machine/arch_atomic.h b/libs/libc/machine/arch_atomic.h new file mode 100644 index 0000000000000..747271912cb5c --- /dev/null +++ b/libs/libc/machine/arch_atomic.h @@ -0,0 +1,320 @@ +/**************************************************************************** + * libs/libc/machine/arch_atomic.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __LIBS_LIBC_MACHINE_ARCH_ATOMIC_H +#define __LIBS_LIBC_MACHINE_ARCH_ATOMIC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define STORE(fn, n, type) \ + \ + void weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value, int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + \ + *(FAR type *)ptr = value; \ + \ + atomic_unlock(irqstate); \ + } + +#define LOAD(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR const volatile void *ptr, \ + int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + \ + type ret = *(FAR type *)ptr; \ + \ + atomic_unlock(irqstate); \ + return ret; \ + } + +#define EXCHANGE(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value, int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + \ + type ret = *tmp; \ + *tmp = value; \ + \ + atomic_unlock(irqstate); \ + return ret; \ + } + +#define CMP_EXCHANGE(fn, n, type) \ + \ + bool weak_function CONCATENATE(fn, n)(FAR volatile void *mem, \ + FAR volatile void *expect, \ + type desired, bool weak, \ + int success, int failure) \ + { \ + bool ret = false; \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmpmem = (FAR type *)mem; \ + FAR type *tmpexp = (FAR type *)expect; \ + \ + if (*tmpmem == *tmpexp) \ + { \ + ret = true; \ + *tmpmem = desired; \ + } \ + else \ + { \ + *tmpexp = *tmpmem; \ + } \ + \ + atomic_unlock(irqstate); \ + return ret; \ + } + +#define FLAG_TEST_AND_SET(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + type ret = *tmp; \ + \ + *(FAR type *)ptr = 1; \ + \ + atomic_unlock(irqstate); \ + return ret; \ + } + +#define FETCH_ADD(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value, int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + type ret = *tmp; \ + \ + *tmp = *tmp + value; \ + \ + atomic_unlock(irqstate); \ + return ret; \ + } + +#define FETCH_SUB(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value, int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + type ret = *tmp; \ + \ + *tmp = *tmp - value; \ + \ + atomic_unlock(irqstate); \ + return ret; \ + } + +#define FETCH_AND(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value, int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + type ret = *tmp; \ + \ + *tmp = *tmp & value; \ + \ + atomic_unlock(irqstate); \ + return ret; \ + } + +#define FETCH_OR(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value, int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + type ret = *tmp; \ + \ + *tmp = *tmp | value; \ + \ + atomic_unlock(irqstate); \ + return ret; \ + } + +#define FETCH_XOR(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value, int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + type ret = *tmp; \ + \ + *tmp = *tmp ^ value; \ + \ + atomic_unlock(irqstate); \ + return ret; \ + } + +#define SYNC_ADD_FETCH(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + \ + *tmp = *tmp + value; \ + \ + atomic_unlock(irqstate); \ + return *tmp; \ + } + +#define SYNC_SUB_FETCH(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + \ + *tmp = *tmp - value; \ + \ + atomic_unlock(irqstate); \ + return *tmp; \ + } + +#define SYNC_OR_FETCH(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + \ + *tmp = *tmp | value; \ + \ + atomic_unlock(irqstate); \ + return *tmp; \ + } + +#define SYNC_AND_FETCH(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + \ + *tmp = *tmp & value; \ + \ + atomic_unlock(irqstate); \ + return *tmp; \ + } + +#define SYNC_XOR_FETCH(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + \ + *tmp = *tmp ^ value; \ + \ + atomic_unlock(irqstate); \ + return *tmp; \ + } + +#define SYNC_NAND_FETCH(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + \ + *tmp = ~(*tmp & value); \ + \ + atomic_unlock(irqstate); \ + return *tmp; \ + } + +#define SYNC_BOOL_CMP_SWAP(fn, n, type) \ + \ + bool weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type oldvalue, \ + type newvalue) \ + { \ + bool ret = false; \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + \ + if (*tmp == oldvalue) \ + { \ + ret = true; \ + *tmp = newvalue; \ + } \ + \ + atomic_unlock(irqstate); \ + return ret; \ + } + +#define SYNC_VAL_CMP_SWAP(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type oldvalue, \ + type newvalue) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + type ret = *tmp; \ + \ + if (*tmp == oldvalue) \ + { \ + *tmp = newvalue; \ + } \ + \ + atomic_unlock(irqstate); \ + return ret; \ + } + +#endif /* __LIBS_LIBC_MACHINE_ARCH_ATOMIC_H */ diff --git a/libs/libc/machine/arch_atomic64.c b/libs/libc/machine/arch_atomic64.c new file mode 100644 index 0000000000000..5b222915fdbf0 --- /dev/null +++ b/libs/libc/machine/arch_atomic64.c @@ -0,0 +1,201 @@ +/**************************************************************************** + * libs/libc/machine/arch_atomic64.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "arch_atomic.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static spinlock_t g_atomic_lock = SP_UNLOCKED; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static inline irqstate_t atomic_lock(void) +{ + return spin_lock_irqsave(&g_atomic_lock); +} + +static inline void atomic_unlock(irqstate_t flags) +{ + spin_unlock_irqrestore(&g_atomic_lock, flags); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: __atomic_store_8 + ****************************************************************************/ + +STORE(__atomic_store_, 8, uint64_t) +#ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN +STORE(nx_atomic_store_, 8, int64_t) +#endif + +/**************************************************************************** + * Name: __atomic_load_8 + ****************************************************************************/ + +LOAD(__atomic_load_, 8, uint64_t) +#ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN +LOAD(nx_atomic_load_, 8, int64_t) +#endif + +/**************************************************************************** + * Name: __atomic_exchange_8 + ****************************************************************************/ + +EXCHANGE(__atomic_exchange_, 8, uint64_t) +#ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN +EXCHANGE(nx_atomic_exchange_, 8, int64_t) +#endif + +/**************************************************************************** + * Name: __atomic_compare_exchange_8 + ****************************************************************************/ + +CMP_EXCHANGE(__atomic_compare_exchange_, 8, uint64_t) +#ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN +CMP_EXCHANGE(nx_atomic_compare_exchange_, 8, int64_t) +#endif + +/**************************************************************************** + * Name: __atomic_flag_test_and_set_8 + ****************************************************************************/ + +FLAG_TEST_AND_SET(__atomic_flags_test_and_set_, 8, uint64_t) +#ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN +FLAG_TEST_AND_SET(nx_atomic_flags_test_and_set_, 8, int64_t) +#endif + +/**************************************************************************** + * Name: __atomic_fetch_add_8 + ****************************************************************************/ + +FETCH_ADD(__atomic_fetch_add_, 8, uint64_t) +#ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN +FETCH_ADD(nx_atomic_fetch_add_, 8, int64_t) +#endif + +/**************************************************************************** + * Name: __atomic_fetch_sub_8 + ****************************************************************************/ + +FETCH_SUB(__atomic_fetch_sub_, 8, uint64_t) +#ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN +FETCH_SUB(nx_atomic_fetch_sub_, 8, int64_t) +#endif + +/**************************************************************************** + * Name: __atomic_fetch_and_8 + ****************************************************************************/ + +FETCH_AND(__atomic_fetch_and_, 8, uint64_t) +#ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN +FETCH_AND(nx_atomic_fetch_and_, 8, int64_t) +#endif + +/**************************************************************************** + * Name: __atomic_fetch_or_8 + ****************************************************************************/ + +FETCH_OR(__atomic_fetch_or_, 8, uint64_t) +#ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN +FETCH_OR(nx_atomic_fetch_or_, 8, int64_t) +#endif + +/**************************************************************************** + * Name: __atomic_fetch_xor_8 + ****************************************************************************/ + +FETCH_XOR(__atomic_fetch_xor_, 8, uint64_t) +#ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN +FETCH_XOR(nx_atomic_fetch_xor_, 8, int64_t) +#endif + +/* Clang define the __sync builtins, add #ifndef to avoid + * redefined/redeclared problem. + */ + +#ifndef __clang__ + +/**************************************************************************** + * Name: __sync_add_and_fetch_8 + ****************************************************************************/ + +SYNC_ADD_FETCH(__sync_add_and_fetch_, 8, uint64_t) + +/**************************************************************************** + * Name: __sync_sub_and_fetch_8 + ****************************************************************************/ + +SYNC_SUB_FETCH(__sync_sub_and_fetch_, 8, uint64_t) + +/**************************************************************************** + * Name: __sync_or_and_fetch_8 + ****************************************************************************/ + +SYNC_OR_FETCH(__sync_or_and_fetch_, 8, uint64_t) + +/**************************************************************************** + * Name: __sync_and_and_fetch_8 + ****************************************************************************/ + +SYNC_AND_FETCH(__sync_and_and_fetch_, 8, uint64_t) + +/**************************************************************************** + * Name: __sync_xor_and_fetch_8 + ****************************************************************************/ + +SYNC_XOR_FETCH(__sync_xor_and_fetch_, 8, uint64_t) + +/**************************************************************************** + * Name: __sync_nand_and_fetch_8 + ****************************************************************************/ + +SYNC_NAND_FETCH(__sync_nand_and_fetch_, 8, uint64_t) + +/**************************************************************************** + * Name: __sync_bool_compare_and_swap_8 + ****************************************************************************/ + +SYNC_BOOL_CMP_SWAP(__sync_bool_compare_and_swap_, 8, uint64_t) + +/**************************************************************************** + * Name: __sync_val_compare_and_swap_8 + ****************************************************************************/ + +SYNC_VAL_CMP_SWAP(__sync_val_compare_and_swap_, 8, uint64_t) + +#endif /* __clang__ */ diff --git a/libs/libc/machine/arch_atomic_irq.c b/libs/libc/machine/arch_atomic_irq.c index 98c0aae5a1cab..4a50d0aa2fbb9 100644 --- a/libs/libc/machine/arch_atomic_irq.c +++ b/libs/libc/machine/arch_atomic_irq.c @@ -28,291 +28,24 @@ #include #include -#include +#include #include +#include "arch_atomic.h" + /**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define STORE(fn, n, type) \ - \ - void weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value, int memorder) \ - { \ - irqstate_t irqstate = up_irq_save(); \ - \ - *(FAR type *)ptr = value; \ - \ - up_irq_restore(irqstate); \ - } - -#define LOAD(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR const volatile void *ptr, \ - int memorder) \ - { \ - irqstate_t irqstate = up_irq_save(); \ - \ - type ret = *(FAR type *)ptr; \ - \ - up_irq_restore(irqstate); \ - return ret; \ - } - -#define EXCHANGE(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value, int memorder) \ - { \ - irqstate_t irqstate = up_irq_save(); \ - FAR type *tmp = (FAR type *)ptr; \ - \ - type ret = *tmp; \ - *tmp = value; \ - \ - up_irq_restore(irqstate); \ - return ret; \ - } - -#define CMP_EXCHANGE(fn, n, type) \ - \ - bool weak_function CONCATENATE(fn, n)(FAR volatile void *mem, \ - FAR volatile void *expect, \ - type desired, bool weak, \ - int success, int failure) \ - { \ - bool ret = false; \ - irqstate_t irqstate = up_irq_save(); \ - FAR type *tmpmem = (FAR type *)mem; \ - FAR type *tmpexp = (FAR type *)expect; \ - \ - if (*tmpmem == *tmpexp) \ - { \ - ret = true; \ - *tmpmem = desired; \ - } \ - else \ - { \ - *tmpexp = *tmpmem; \ - } \ - \ - up_irq_restore(irqstate); \ - return ret; \ - } - -#define FLAG_TEST_AND_SET(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - int memorder) \ - { \ - irqstate_t irqstate = up_irq_save(); \ - FAR type *tmp = (FAR type *)ptr; \ - type ret = *tmp; \ - \ - *(FAR type *)ptr = 1; \ - \ - up_irq_restore(irqstate); \ - return ret; \ - } - -#define FETCH_ADD(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value, int memorder) \ - { \ - irqstate_t irqstate = up_irq_save(); \ - FAR type *tmp = (FAR type *)ptr; \ - type ret = *tmp; \ - \ - *tmp = *tmp + value; \ - \ - up_irq_restore(irqstate); \ - return ret; \ - } - -#define FETCH_SUB(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value, int memorder) \ - { \ - irqstate_t irqstate = up_irq_save(); \ - FAR type *tmp = (FAR type *)ptr; \ - type ret = *tmp; \ - \ - *tmp = *tmp - value; \ - \ - up_irq_restore(irqstate); \ - return ret; \ - } - -#define FETCH_AND(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value, int memorder) \ - { \ - irqstate_t irqstate = up_irq_save(); \ - FAR type *tmp = (FAR type *)ptr; \ - type ret = *tmp; \ - \ - *tmp = *tmp & value; \ - \ - up_irq_restore(irqstate); \ - return ret; \ - } - -#define FETCH_OR(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value, int memorder) \ - { \ - irqstate_t irqstate = up_irq_save(); \ - FAR type *tmp = (FAR type *)ptr; \ - type ret = *tmp; \ - \ - *tmp = *tmp | value; \ - \ - up_irq_restore(irqstate); \ - return ret; \ - } - -#define FETCH_XOR(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value, int memorder) \ - { \ - irqstate_t irqstate = up_irq_save(); \ - FAR type *tmp = (FAR type *)ptr; \ - type ret = *tmp; \ - \ - *tmp = *tmp ^ value; \ - \ - up_irq_restore(irqstate); \ - return ret; \ - } - -#define SYNC_ADD_FETCH(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value) \ - { \ - irqstate_t irqstate = up_irq_save(); \ - FAR type *tmp = (FAR type *)ptr; \ - \ - *tmp = *tmp + value; \ - \ - up_irq_restore(irqstate); \ - return *tmp; \ - } - -#define SYNC_SUB_FETCH(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value) \ - { \ - irqstate_t irqstate = up_irq_save(); \ - FAR type *tmp = (FAR type *)ptr; \ - \ - *tmp = *tmp - value; \ - \ - up_irq_restore(irqstate); \ - return *tmp; \ - } - -#define SYNC_OR_FETCH(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value) \ - { \ - irqstate_t irqstate = up_irq_save(); \ - FAR type *tmp = (FAR type *)ptr; \ - \ - *tmp = *tmp | value; \ - \ - up_irq_restore(irqstate); \ - return *tmp; \ - } - -#define SYNC_AND_FETCH(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value) \ - { \ - irqstate_t irqstate = up_irq_save(); \ - FAR type *tmp = (FAR type *)ptr; \ - \ - *tmp = *tmp & value; \ - \ - up_irq_restore(irqstate); \ - return *tmp; \ - } - -#define SYNC_XOR_FETCH(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value) \ - { \ - irqstate_t irqstate = up_irq_save(); \ - FAR type *tmp = (FAR type *)ptr; \ - \ - *tmp = *tmp ^ value; \ - \ - up_irq_restore(irqstate); \ - return *tmp; \ - } - -#define SYNC_NAND_FETCH(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value) \ - { \ - irqstate_t irqstate = up_irq_save(); \ - FAR type *tmp = (FAR type *)ptr; \ - \ - *tmp = ~(*tmp & value); \ - \ - up_irq_restore(irqstate); \ - return *tmp; \ - } - -#define SYNC_BOOL_CMP_SWAP(fn, n, type) \ - \ - bool weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type oldvalue, \ - type newvalue) \ - { \ - bool ret = false; \ - irqstate_t irqstate = up_irq_save(); \ - FAR type *tmp = (FAR type *)ptr; \ - \ - if (*tmp == oldvalue) \ - { \ - ret = true; \ - *tmp = newvalue; \ - } \ - \ - up_irq_restore(irqstate); \ - return ret; \ - } - -#define SYNC_VAL_CMP_SWAP(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type oldvalue, \ - type newvalue) \ - { \ - irqstate_t irqstate = up_irq_save(); \ - FAR type *tmp = (FAR type *)ptr; \ - type ret = *tmp; \ - \ - if (*tmp == oldvalue) \ - { \ - *tmp = newvalue; \ - } \ - \ - up_irq_restore(irqstate); \ - return ret; \ - } + * Private Functions + ****************************************************************************/ + +static inline irqstate_t atomic_lock(void) +{ + return up_irq_save(); +} + +static inline void atomic_unlock(irqstate_t flags) +{ + up_irq_restore(flags); +} /**************************************************************************** * Public Functions @@ -337,13 +70,6 @@ STORE(__atomic_store_, 2, uint16_t) STORE(__atomic_store_, 4, uint32_t) STORE(nx_atomic_store_, 4, int32_t) -/**************************************************************************** - * Name: __atomic_store_8 - ****************************************************************************/ - -STORE(__atomic_store_, 8, uint64_t) -STORE(nx_atomic_store_, 8, int64_t) - /**************************************************************************** * Name: __atomic_load_1 ****************************************************************************/ @@ -351,25 +77,18 @@ STORE(nx_atomic_store_, 8, int64_t) LOAD(__atomic_load_, 1, uint8_t) /**************************************************************************** - * Name: __atomic_load__2 + * Name: __atomic_load_2 ****************************************************************************/ LOAD(__atomic_load_, 2, uint16_t) /**************************************************************************** - * Name: __atomic_load__4 + * Name: __atomic_load_4 ****************************************************************************/ LOAD(__atomic_load_, 4, uint32_t) LOAD(nx_atomic_load_, 4, int32_t) -/**************************************************************************** - * Name: __atomic_load__8 - ****************************************************************************/ - -LOAD(__atomic_load_, 8, uint64_t) -LOAD(nx_atomic_load_, 8, int64_t) - /**************************************************************************** * Name: __atomic_exchange_1 ****************************************************************************/ @@ -377,25 +96,18 @@ LOAD(nx_atomic_load_, 8, int64_t) EXCHANGE(__atomic_exchange_, 1, uint8_t) /**************************************************************************** - * Name: __atomic_exchange__2 + * Name: __atomic_exchange_2 ****************************************************************************/ EXCHANGE(__atomic_exchange_, 2, uint16_t) /**************************************************************************** - * Name: __atomic_exchange__4 + * Name: __atomic_exchange_4 ****************************************************************************/ EXCHANGE(__atomic_exchange_, 4, uint32_t) EXCHANGE(nx_atomic_exchange_, 4, int32_t) -/**************************************************************************** - * Name: __atomic_exchange__8 - ****************************************************************************/ - -EXCHANGE(__atomic_exchange_, 8, uint64_t) -EXCHANGE(nx_atomic_exchange_, 8, int64_t) - /**************************************************************************** * Name: __atomic_compare_exchange_1 ****************************************************************************/ @@ -415,13 +127,6 @@ CMP_EXCHANGE(__atomic_compare_exchange_, 2, uint16_t) CMP_EXCHANGE(__atomic_compare_exchange_, 4, uint32_t) CMP_EXCHANGE(nx_atomic_compare_exchange_, 4, int32_t) -/**************************************************************************** - * Name: __atomic_compare_exchange_8 - ****************************************************************************/ - -CMP_EXCHANGE(__atomic_compare_exchange_, 8, uint64_t) -CMP_EXCHANGE(nx_atomic_compare_exchange_, 8, int64_t) - /**************************************************************************** * Name: __atomic_flag_test_and_set_1 ****************************************************************************/ @@ -441,13 +146,6 @@ FLAG_TEST_AND_SET(__atomic_flags_test_and_set_, 2, uint16_t) FLAG_TEST_AND_SET(__atomic_flags_test_and_set_, 4, uint32_t) FLAG_TEST_AND_SET(nx_atomic_flags_test_and_set_, 4, int32_t) -/**************************************************************************** - * Name: __atomic_flag_test_and_set_8 - ****************************************************************************/ - -FLAG_TEST_AND_SET(__atomic_flags_test_and_set_, 8, uint64_t) -FLAG_TEST_AND_SET(nx_atomic_flags_test_and_set_, 8, int64_t) - /**************************************************************************** * Name: __atomic_fetch_add_1 ****************************************************************************/ @@ -467,13 +165,6 @@ FETCH_ADD(__atomic_fetch_add_, 2, uint16_t) FETCH_ADD(__atomic_fetch_add_, 4, uint32_t) FETCH_ADD(nx_atomic_fetch_add_, 4, int32_t) -/**************************************************************************** - * Name: __atomic_fetch_add_8 - ****************************************************************************/ - -FETCH_ADD(__atomic_fetch_add_, 8, uint64_t) -FETCH_ADD(nx_atomic_fetch_add_, 8, int64_t) - /**************************************************************************** * Name: __atomic_fetch_sub_1 ****************************************************************************/ @@ -493,13 +184,6 @@ FETCH_SUB(__atomic_fetch_sub_, 2, uint16_t) FETCH_SUB(__atomic_fetch_sub_, 4, uint32_t) FETCH_SUB(nx_atomic_fetch_sub_, 4, int32_t) -/**************************************************************************** - * Name: __atomic_fetch_sub_8 - ****************************************************************************/ - -FETCH_SUB(__atomic_fetch_sub_, 8, uint64_t) -FETCH_SUB(nx_atomic_fetch_sub_, 8, int64_t) - /**************************************************************************** * Name: __atomic_fetch_and_1 ****************************************************************************/ @@ -519,13 +203,6 @@ FETCH_AND(__atomic_fetch_and_, 2, uint16_t) FETCH_AND(__atomic_fetch_and_, 4, uint32_t) FETCH_AND(nx_atomic_fetch_and_, 4, int32_t) -/**************************************************************************** - * Name: __atomic_fetch_and_8 - ****************************************************************************/ - -FETCH_AND(__atomic_fetch_and_, 8, uint64_t) -FETCH_AND(nx_atomic_fetch_and_, 8, int64_t) - /**************************************************************************** * Name: __atomic_fetch_or_1 ****************************************************************************/ @@ -545,13 +222,6 @@ FETCH_OR(__atomic_fetch_or_, 2, uint16_t) FETCH_OR(__atomic_fetch_or_, 4, uint32_t) FETCH_OR(nx_atomic_fetch_or_, 4, int32_t) -/**************************************************************************** - * Name: __atomic_fetch_or_4 - ****************************************************************************/ - -FETCH_OR(__atomic_fetch_or_, 8, uint64_t) -FETCH_OR(nx_atomic_fetch_or_, 8, int64_t) - /**************************************************************************** * Name: __atomic_fetch_xor_1 ****************************************************************************/ @@ -571,13 +241,6 @@ FETCH_XOR(__atomic_fetch_xor_, 2, uint16_t) FETCH_XOR(__atomic_fetch_xor_, 4, uint32_t) FETCH_XOR(nx_atomic_fetch_xor_, 4, int32_t) -/**************************************************************************** - * Name: __atomic_fetch_xor_8 - ****************************************************************************/ - -FETCH_XOR(__atomic_fetch_xor_, 8, uint64_t) -FETCH_XOR(nx_atomic_fetch_xor_, 8, int64_t) - /* Clang define the __sync builtins, add #ifndef to avoid * redefined/redeclared problem. */ @@ -602,12 +265,6 @@ SYNC_ADD_FETCH(__sync_add_and_fetch_, 2, uint16_t) SYNC_ADD_FETCH(__sync_add_and_fetch_, 4, uint32_t) -/**************************************************************************** - * Name: __sync_add_and_fetch_8 - ****************************************************************************/ - -SYNC_ADD_FETCH(__sync_add_and_fetch_, 8, uint64_t) - /**************************************************************************** * Name: __sync_sub_and_fetch_1 ****************************************************************************/ @@ -626,12 +283,6 @@ SYNC_SUB_FETCH(__sync_sub_and_fetch_, 2, uint16_t) SYNC_SUB_FETCH(__sync_sub_and_fetch_, 4, uint32_t) -/**************************************************************************** - * Name: __sync_sub_and_fetch_8 - ****************************************************************************/ - -SYNC_SUB_FETCH(__sync_sub_and_fetch_, 8, uint64_t) - /**************************************************************************** * Name: __sync_or_and_fetch_1 ****************************************************************************/ @@ -650,12 +301,6 @@ SYNC_OR_FETCH(__sync_or_and_fetch_, 2, uint16_t) SYNC_OR_FETCH(__sync_or_and_fetch_, 4, uint32_t) -/**************************************************************************** - * Name: __sync_or_and_fetch_8 - ****************************************************************************/ - -SYNC_OR_FETCH(__sync_or_and_fetch_, 8, uint64_t) - /**************************************************************************** * Name: __sync_and_and_fetch_1 ****************************************************************************/ @@ -674,12 +319,6 @@ SYNC_AND_FETCH(__sync_and_and_fetch_, 2, uint16_t) SYNC_AND_FETCH(__sync_and_and_fetch_, 4, uint32_t) -/**************************************************************************** - * Name: __sync_and_and_fetch_8 - ****************************************************************************/ - -SYNC_AND_FETCH(__sync_and_and_fetch_, 8, uint64_t) - /**************************************************************************** * Name: __sync_xor_and_fetch_1 ****************************************************************************/ @@ -698,12 +337,6 @@ SYNC_XOR_FETCH(__sync_xor_and_fetch_, 2, uint16_t) SYNC_XOR_FETCH(__sync_xor_and_fetch_, 4, uint32_t) -/**************************************************************************** - * Name: __sync_xor_and_fetch_8 - ****************************************************************************/ - -SYNC_XOR_FETCH(__sync_xor_and_fetch_, 8, uint64_t) - /**************************************************************************** * Name: __sync_nand_and_fetch_1 ****************************************************************************/ @@ -722,12 +355,6 @@ SYNC_NAND_FETCH(__sync_nand_and_fetch_, 2, uint16_t) SYNC_NAND_FETCH(__sync_nand_and_fetch_, 4, uint32_t) -/**************************************************************************** - * Name: __sync_nand_and_fetch_8 - ****************************************************************************/ - -SYNC_NAND_FETCH(__sync_nand_and_fetch_, 8, uint64_t) - /**************************************************************************** * Name: __sync_bool_compare_and_swap_1 ****************************************************************************/ @@ -746,12 +373,6 @@ SYNC_BOOL_CMP_SWAP(__sync_bool_compare_and_swap_, 2, uint16_t) SYNC_BOOL_CMP_SWAP(__sync_bool_compare_and_swap_, 4, uint32_t) -/**************************************************************************** - * Name: __sync_bool_compare_and_swap_8 - ****************************************************************************/ - -SYNC_BOOL_CMP_SWAP(__sync_bool_compare_and_swap_, 8, uint64_t) - /**************************************************************************** * Name: __sync_val_compare_and_swap_1 ****************************************************************************/ @@ -770,12 +391,6 @@ SYNC_VAL_CMP_SWAP(__sync_val_compare_and_swap_, 2, uint16_t) SYNC_VAL_CMP_SWAP(__sync_val_compare_and_swap_, 4, uint32_t) -/**************************************************************************** - * Name: __sync_val_compare_and_swap_8 - ****************************************************************************/ - -SYNC_VAL_CMP_SWAP(__sync_val_compare_and_swap_, 8, uint64_t) - /**************************************************************************** * Name: __sync_synchronize ****************************************************************************/ From a78428403b30cf4286f0b2cb11cc01f73b2769e2 Mon Sep 17 00:00:00 2001 From: zhangyu117 Date: Fri, 14 Aug 2026 14:42:59 +0800 Subject: [PATCH 05/14] nuttx/atomic: select LIBC_ATOMIC_IRQ for archs without atomic support Select LIBC_ATOMIC_IRQ at the architecture level (ARM7TDMI, ARM926EJS, ARMv6M) for chips that do not support atomic operations natively. This covers all ARM7TDMI, ARM926EJS, and Cortex-M0 based chips automatically. Also select LIBC_ATOMIC_IRQ for specific non-ARM architectures (AVR, RISC-V, SPARC, Xtensa) that lack atomic instruction support. Signed-off-by: zhangyu117 --- arch/arm/Kconfig | 3 +++ arch/arm/src/s32k1xx/Kconfig | 1 + arch/avr/Kconfig | 4 ++++ arch/risc-v/Kconfig | 4 ++++ arch/sparc/Kconfig | 2 ++ arch/xtensa/Kconfig | 1 + 6 files changed, 15 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 15b36b1cb13cb..0b8128a44c0ff 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -965,6 +965,7 @@ config ARCH_ARM7TDMI default n select ARCH_DCACHE select ARCH_ICACHE + select LIBC_ATOMIC_IRQ ---help--- The Arm7TDMI-S is an excellent workhorse processor capable of a wide array of applications. Traditionally used in mobile handsets, the @@ -994,6 +995,7 @@ config ARCH_ARM926EJS select ARCH_ICACHE select ARCH_HAVE_MMU select ARCH_USE_MMU + select LIBC_ATOMIC_IRQ ---help--- Arm926EJ-S is the entry point processor capable of supporting full Operating Systems including Linux, WindowsCE, and Symbian. @@ -1049,6 +1051,7 @@ config ARCH_ARMV6M bool default n select ARCH_HAVE_CPUINFO + select LIBC_ATOMIC_IRQ config ARCH_CORTEXM0 bool diff --git a/arch/arm/src/s32k1xx/Kconfig b/arch/arm/src/s32k1xx/Kconfig index b71c5d1412d7b..496e287787700 100644 --- a/arch/arm/src/s32k1xx/Kconfig +++ b/arch/arm/src/s32k1xx/Kconfig @@ -75,6 +75,7 @@ config ARCH_CHIP_S32K11X bool select ARCH_CORTEXM0 select S32K1XX_HAVE_FIRC_CMU + select LIBC_ATOMIC_IRQ config ARCH_CHIP_S32K14X bool diff --git a/arch/avr/Kconfig b/arch/avr/Kconfig index 771274f1c00d8..e56302d7e908d 100644 --- a/arch/avr/Kconfig +++ b/arch/avr/Kconfig @@ -13,12 +13,14 @@ config ARCH_CHIP_ATMEGA bool "ATMega family" select ARCH_FAMILY_AVR select MM_SMALL + select LIBC_ATOMIC_IRQ ---help--- Atmel ATMega family of 8-bit AVRs. config ARCH_CHIP_AT90USB bool "AT90USB family" select ARCH_FAMILY_AVR + select LIBC_ATOMIC_IRQ select MM_SMALL ---help--- Atmel AT90USB family of 8-bit AVRs. @@ -35,12 +37,14 @@ config ARCH_CHIP_AVRDX config ARCH_CHIP_AT32UC3 bool "AVR32 AT32UC3* family" select ARCH_FAMILY_AVR32 + select LIBC_ATOMIC_IRQ ---help--- Atmel AT32UC3A/B/C family of 32-bit AVR32s. config ARCH_CHIP_AVR_CUSTOM bool "Custom AVR chip" select ARCH_CHIP_CUSTOM + select LIBC_ATOMIC_IRQ ---help--- Select this option if there is no directory for the chip under arch/avr/src/. diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index dabc4d902a55f..17bc1566a7124 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -113,6 +113,7 @@ config ARCH_CHIP_ESP32C3_LEGACY select ARCH_HAVE_RAMFUNCS select ONESHOT_COUNT if ONESHOT select ONESHOT_FAST_DIVISION if ONESHOT + select LIBC_ATOMIC_IRQ ---help--- Espressif ESP32-C3 (RV32IMC). Legacy implementation. @@ -146,6 +147,7 @@ config ARCH_CHIP_ESP32C3 select ONESHOT_COUNT if ONESHOT select ONESHOT_FAST_DIVISION if ONESHOT select ARCH_MINIMAL_VECTORTABLE + select LIBC_ATOMIC_IRQ ---help--- ESP32-C3 chip with a single RISC-V IMC core, no embedded Flash memory @@ -211,6 +213,7 @@ config ARCH_CHIP_ESP32H2 select ONESHOT_COUNT if ONESHOT select ONESHOT_FAST_DIVISION if ONESHOT select ARCH_MINIMAL_VECTORTABLE + select LIBC_ATOMIC_IRQ ---help--- Espressif ESP32-H2 (RV32IMC). @@ -297,6 +300,7 @@ config ARCH_CHIP_RV32M1 select ONESHOT_COUNT select ONESHOT_FAST_DIVISION select ALARM_ARCH + select LIBC_ATOMIC_IRQ ---help--- NXP RV32M1 processor (RISC-V Core with PULP extensions). diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index d5248a1765cb1..4f950eee3b23c 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -18,6 +18,7 @@ config ARCH_CHIP_BM3803 select ARCH_HAVE_RAMFUNCS select ARCH_HAVE_TICKLESS select ARCH_HAVE_SERIAL_TERMIOS + select LIBC_ATOMIC_IRQ ---help--- Microchip BM3803 (ARCH_SPARC_V8) @@ -29,6 +30,7 @@ config ARCH_CHIP_BM3823 select ARCH_VECNOTIRQ select ARCH_HAVE_RAMFUNCS select ARCH_HAVE_SERIAL_TERMIOS + select LIBC_ATOMIC_IRQ ---help--- Microchip BM3823 (ARCH_SPARC_V8) diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 5f25569d86687..b4ec0f3eedb27 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -70,6 +70,7 @@ config ARCH_CHIP_ESP32S2 select LIBC_ARCH_STRNCPY select LIBC_ARCH_STRLEN select LIBC_ARCH_STRNLEN + select LIBC_ATOMIC_IRQ ---help--- ESP32-S2 is a truly secure, highly integrated, low-power, 2.4 GHz Wi-Fi Microcontroller SoC supporting Wi-Fi HT40 and having 43 GPIOs. From 4cf79fc19fdef98e7b481acd9e69a96f31a6a419 Mon Sep 17 00:00:00 2001 From: zhangyu117 Date: Fri, 14 Aug 2026 17:29:16 +0800 Subject: [PATCH 06/14] nuttx: use unified interface in Replace atomic_load with atomic_read in call sites to use the unified interface defined in . Signed-off-by: zhangyu117 --- drivers/rpmsg/rpmsg_port_spi.c | 2 +- drivers/rpmsg/rpmsg_port_spi_slave.c | 2 +- drivers/serial/pty.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/rpmsg/rpmsg_port_spi.c b/drivers/rpmsg/rpmsg_port_spi.c index fb6c34bc98621..8d3eea04959e3 100644 --- a/drivers/rpmsg/rpmsg_port_spi.c +++ b/drivers/rpmsg/rpmsg_port_spi.c @@ -162,7 +162,7 @@ static void rpmsg_port_spi_pm_callback(wdparm_t arg) flags = spin_lock_irqsave(&rpspi->pmlock); count = pm_wakelock_staycount(&rpspi->wakelock); - if (count > 0 && atomic_load(&rpspi->transferring) == 0 && + if (count > 0 && atomic_read(&rpspi->transferring) == 0 && rpmsg_port_queue_nused(&rpspi->port.txq) == 0 && rpmsg_port_queue_nused(&rpspi->port.rxq) == 0) { diff --git a/drivers/rpmsg/rpmsg_port_spi_slave.c b/drivers/rpmsg/rpmsg_port_spi_slave.c index b1660a996cef4..1a8e0ab63fc2a 100644 --- a/drivers/rpmsg/rpmsg_port_spi_slave.c +++ b/drivers/rpmsg/rpmsg_port_spi_slave.c @@ -190,7 +190,7 @@ static void rpmsg_port_spi_pm_callback(wdparm_t arg) flags = spin_lock_irqsave(&rpspi->pmlock); count = pm_wakelock_staycount(&rpspi->wakelock); - if (count > 0 && atomic_load(&rpspi->transferring) == 0 && + if (count > 0 && atomic_read(&rpspi->transferring) == 0 && rpmsg_port_queue_nused(&rpspi->port.txq) == 0 && rpmsg_port_queue_nused(&rpspi->port.rxq) == 0) { diff --git a/drivers/serial/pty.c b/drivers/serial/pty.c index f2b7c091352d1..c4f2eab5ce7d9 100644 --- a/drivers/serial/pty.c +++ b/drivers/serial/pty.c @@ -358,8 +358,8 @@ static int pty_close(FAR struct file *filep) /* Check if the decremented inode reference count would go to zero */ - if ((!dev->pd_master && atomic_load(&inode->i_crefs) == 2) || - (dev->pd_master && atomic_load(&inode->i_crefs) == 1)) + if ((!dev->pd_master && atomic_read(&inode->i_crefs) == 2) || + (dev->pd_master && atomic_read(&inode->i_crefs) == 1)) { /* Did the (single) master just close its reference? */ From eeb836e0e7a5f30d2c4e759d54aa797ea4bd7e6b Mon Sep 17 00:00:00 2001 From: zhangyu117 Date: Wed, 19 Aug 2026 12:11:29 +0800 Subject: [PATCH 07/14] nuttx/atomic: for builtin atomic, a wrapper is used to unify the names. 1. for tasking, map __c11_atomic_xxx as tasking_atomic_xxx 2. for msvc, map _Interlocked_xxx as msvc_atomic_xxx 3. if no special map, use gcc/clang as default as they are most widely used. Signed-off-by: zhangyu117 --- include/nuttx/compiler.h | 109 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/include/nuttx/compiler.h b/include/nuttx/compiler.h index 0c2af726c156f..32a2a96d765f3 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 From d0ba0d014eaefae96b34ab8d42a05cdc04f6e5c5 Mon Sep 17 00:00:00 2001 From: zhangyu117 Date: Wed, 19 Aug 2026 12:13:03 +0800 Subject: [PATCH 08/14] nuttx/atomic: use toolchain builtin atomic function The reason for using builtin atomic is that in C++, when include in easily conflicts with third-party function libraries. We wanted to completely separate the implementation of . There are two points: 1. use builtin function directly. 2. Without the standard library implementation, need implement "atomic_fetch_xxx", leading conflicts with the standard library used by third-party programs, introducing redefinition issues and requiring name changes. Signed-off-by: zhangyu117 --- include/nuttx/atomic.h | 321 ++++++++++-------------- libs/libc/machine/arch_atomic64.c | 20 +- libs/libc/machine/arch_atomic_irq.c | 20 +- libs/libc/machine/tricore/arch_atomic.c | 30 +-- 4 files changed, 166 insertions(+), 225 deletions(-) diff --git a/include/nuttx/atomic.h b/include/nuttx/atomic.h index d2ea13d9e446b..9f466ff7dd4f1 100644 --- a/include/nuttx/atomic.h +++ b/include/nuttx/atomic.h @@ -29,53 +29,9 @@ #include -#define NEED_ATOMIC_MACROS -#if defined(__has_include) -# if __has_include() && defined(__cplusplus) -# undef NEED_ATOMIC_MACROS -# endif -#endif - -#if defined(CONFIG_LIBC_ATOMIC_TOOLCHAIN) -# if __has_include() && defined(__cplusplus) -extern "C++" -{ -# include -# define ATOMIC_FUNC(f, n) atomic_##f##_explicit - - using std::atomic_load_explicit; - using std::atomic_store_explicit; - using std::atomic_exchange_explicit; - using std::atomic_compare_exchange_strong_explicit; - using std::atomic_compare_exchange_weak_explicit; - using std::atomic_fetch_add_explicit; - using std::atomic_fetch_sub_explicit; - using std::atomic_fetch_and_explicit; - using std::atomic_fetch_or_explicit; - using std::atomic_fetch_xor_explicit; - - typedef volatile int32_t atomic_t; - typedef volatile int64_t atomic64_t; -} -# elif ((defined(__cplusplus) && __cplusplus >= 201103L) || \ - (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)) && \ - !defined(__STDC_NO_ATOMICS__) -# if !defined(__clang__) && defined(__cplusplus) -# define _Atomic -# endif -# include -# define ATOMIC_FUNC(f, n) atomic_##f##_explicit - -# if defined(__cplusplus) -# define __auto_type auto -typedef _Atomic int32_t atomic_t; -typedef _Atomic int64_t atomic64_t; -# else -typedef volatile _Atomic int32_t atomic_t; -typedef volatile _Atomic int64_t atomic64_t; -# endif -# endif -#endif +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ #ifndef __ATOMIC_RELAXED # define __ATOMIC_RELAXED 0 @@ -101,130 +57,111 @@ typedef volatile _Atomic int64_t atomic64_t; # define __ATOMIC_SEQ_CST 5 #endif -#ifndef ATOMIC_FUNC - -# define ATOMIC_FUNC(f, n) nx_atomic_##f##_##n - -# define nx_atomic_compare_exchange_weak_4(obj, expect, desired, success, failure) \ - nx_atomic_compare_exchange_4(obj, expect, desired, true, success, failure) -# define nx_atomic_compare_exchange_weak_8(obj, expect, desired, success, failure) \ - nx_atomic_compare_exchange_8(obj, expect, desired, true, success, failure) -# define nx_atomic_compare_exchange_strong_4(obj, expect, desired, success, failure) \ - nx_atomic_compare_exchange_4(obj, expect, desired, false, success, failure) -# define nx_atomic_compare_exchange_strong_8(obj, expect, desired, success, failure) \ - nx_atomic_compare_exchange_8(obj, expect, desired, false, success, failure) - -typedef volatile int32_t atomic_t; -typedef volatile int64_t atomic64_t; -#endif - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef NEED_ATOMIC_MACROS - -#define atomic_set(obj, val) ATOMIC_FUNC(store, 4)(obj, val, __ATOMIC_RELAXED) -#define atomic_set_release(obj, val) ATOMIC_FUNC(store, 4)(obj, val, __ATOMIC_RELEASE) -#define atomic64_set(obj, val) ATOMIC_FUNC(store, 8)(obj, val, __ATOMIC_RELAXED) -#define atomic64_set_release(obj, val) ATOMIC_FUNC(store, 8)(obj, val, __ATOMIC_RELEASE) - -#define atomic_read(obj) ATOMIC_FUNC(load, 4)(obj, __ATOMIC_RELAXED) -#define atomic_read_acquire(obj) ATOMIC_FUNC(load, 4)(obj, __ATOMIC_ACQUIRE) -#define atomic64_read(obj) ATOMIC_FUNC(load, 8)(obj, __ATOMIC_RELAXED) -#define atomic64_read_acquire(obj) ATOMIC_FUNC(load, 8)(obj, __ATOMIC_ACQUIRE) - -#define atomic_fetch_add(obj, val) ATOMIC_FUNC(fetch_add, 4)(obj, val, __ATOMIC_ACQ_REL) -#define atomic_fetch_add_acquire(obj, val) ATOMIC_FUNC(fetch_add, 4)(obj, val, __ATOMIC_ACQUIRE) -#define atomic_fetch_add_release(obj, val) ATOMIC_FUNC(fetch_add, 4)(obj, val, __ATOMIC_RELEASE) -#define atomic_fetch_add_relaxed(obj, val) ATOMIC_FUNC(fetch_add, 4)(obj, val, __ATOMIC_RELAXED) -#define atomic64_fetch_add(obj, val) ATOMIC_FUNC(fetch_add, 8)(obj, val, __ATOMIC_ACQ_REL) -#define atomic64_fetch_add_acquire(obj, val) ATOMIC_FUNC(fetch_add, 8)(obj, val, __ATOMIC_ACQUIRE) -#define atomic64_fetch_add_release(obj, val) ATOMIC_FUNC(fetch_add, 8)(obj, val, __ATOMIC_RELEASE) -#define atomic64_fetch_add_relaxed(obj, val) ATOMIC_FUNC(fetch_add, 8)(obj, val, __ATOMIC_RELAXED) - -#define atomic_fetch_sub(obj, val) ATOMIC_FUNC(fetch_sub, 4)(obj, val, __ATOMIC_ACQ_REL) -#define atomic_fetch_sub_acquire(obj, val) ATOMIC_FUNC(fetch_sub, 4)(obj, val, __ATOMIC_ACQUIRE) -#define atomic_fetch_sub_release(obj, val) ATOMIC_FUNC(fetch_sub, 4)(obj, val, __ATOMIC_RELEASE) -#define atomic_fetch_sub_relaxed(obj, val) ATOMIC_FUNC(fetch_sub, 4)(obj, val, __ATOMIC_RELAXED) -#define atomic64_fetch_sub(obj, val) ATOMIC_FUNC(fetch_sub, 8)(obj, val, __ATOMIC_ACQ_REL) -#define atomic64_fetch_sub_acquire(obj, val) ATOMIC_FUNC(fetch_sub, 8)(obj, val, __ATOMIC_ACQUIRE) -#define atomic64_fetch_sub_release(obj, val) ATOMIC_FUNC(fetch_sub, 8)(obj, val, __ATOMIC_RELEASE) -#define atomic64_fetch_sub_relaxed(obj, val) ATOMIC_FUNC(fetch_sub, 8)(obj, val, __ATOMIC_RELAXED) - -#define atomic_fetch_and(obj, val) ATOMIC_FUNC(fetch_and, 4)(obj, val, __ATOMIC_ACQ_REL) -#define atomic_fetch_and_acquire(obj, val) ATOMIC_FUNC(fetch_and, 4)(obj, val, __ATOMIC_ACQUIRE) -#define atomic_fetch_and_release(obj, val) ATOMIC_FUNC(fetch_and, 4)(obj, val, __ATOMIC_RELEASE) -#define atomic_fetch_and_relaxed(obj, val) ATOMIC_FUNC(fetch_and, 4)(obj, val, __ATOMIC_RELAXED) -#define atomic64_fetch_and(obj, val) ATOMIC_FUNC(fetch_and, 8)(obj, val, __ATOMIC_ACQ_REL) -#define atomic64_fetch_and_acquire(obj, val) ATOMIC_FUNC(fetch_and, 8)(obj, val, __ATOMIC_ACQUIRE) -#define atomic64_fetch_and_release(obj, val) ATOMIC_FUNC(fetch_and, 8)(obj, val, __ATOMIC_RELEASE) -#define atomic64_fetch_and_relaxed(obj, val) ATOMIC_FUNC(fetch_and, 8)(obj, val, __ATOMIC_RELAXED) - -#define atomic_fetch_or(obj, val) ATOMIC_FUNC(fetch_or, 4)(obj, val, __ATOMIC_ACQ_REL) -#define atomic_fetch_or_acquire(obj, val) ATOMIC_FUNC(fetch_or, 4)(obj, val, __ATOMIC_ACQUIRE) -#define atomic_fetch_or_release(obj, val) ATOMIC_FUNC(fetch_or, 4)(obj, val, __ATOMIC_RELEASE) -#define atomic_fetch_or_relaxed(obj, val) ATOMIC_FUNC(fetch_or, 4)(obj, val, __ATOMIC_RELAXED) -#define atomic64_fetch_or(obj, val) ATOMIC_FUNC(fetch_or, 8)(obj, val, __ATOMIC_ACQ_REL) -#define atomic64_fetch_or_acquire(obj, val) ATOMIC_FUNC(fetch_or, 8)(obj, val, __ATOMIC_ACQUIRE) -#define atomic64_fetch_or_release(obj, val) ATOMIC_FUNC(fetch_or, 8)(obj, val, __ATOMIC_RELEASE) -#define atomic64_fetch_or_relaxed(obj, val) ATOMIC_FUNC(fetch_or, 8)(obj, val, __ATOMIC_RELAXED) - -#define atomic_fetch_xor(obj, val) ATOMIC_FUNC(fetch_xor, 4)(obj, val, __ATOMIC_ACQ_REL) -#define atomic_fetch_xor_acquire(obj, val) ATOMIC_FUNC(fetch_xor, 4)(obj, val, __ATOMIC_ACQUIRE) -#define atomic_fetch_xor_release(obj, val) ATOMIC_FUNC(fetch_xor, 4)(obj, val, __ATOMIC_RELEASE) -#define atomic_fetch_xor_relaxed(obj, val) ATOMIC_FUNC(fetch_xor, 4)(obj, val, __ATOMIC_RELAXED) -#define atomic64_fetch_xor(obj, val) ATOMIC_FUNC(fetch_xor, 8)(obj, val, __ATOMIC_ACQ_REL) -#define atomic64_fetch_xor_acquire(obj, val) ATOMIC_FUNC(fetch_xor, 8)(obj, val, __ATOMIC_ACQUIRE) -#define atomic64_fetch_xor_release(obj, val) ATOMIC_FUNC(fetch_xor, 8)(obj, val, __ATOMIC_RELEASE) -#define atomic64_fetch_xor_relaxed(obj, val) ATOMIC_FUNC(fetch_xor, 8)(obj, val, __ATOMIC_RELAXED) - -#define atomic_xchg(obj, val) ATOMIC_FUNC(exchange, 4)(obj, val, __ATOMIC_ACQ_REL) -#define atomic_xchg_acquire(obj, val) ATOMIC_FUNC(exchange, 4)(obj, val, __ATOMIC_ACQUIRE) -#define atomic_xchg_release(obj, val) ATOMIC_FUNC(exchange, 4)(obj, val, __ATOMIC_RELEASE) -#define atomic_xchg_relaxed(obj, val) ATOMIC_FUNC(exchange, 4)(obj, val, __ATOMIC_RELAXED) -#define atomic64_xchg(obj, val) ATOMIC_FUNC(exchange, 8)(obj, val, __ATOMIC_ACQ_REL) -#define atomic64_xchg_acquire(obj, val) ATOMIC_FUNC(exchange, 8)(obj, val, __ATOMIC_ACQUIRE) -#define atomic64_xchg_release(obj, val) ATOMIC_FUNC(exchange, 8)(obj, val, __ATOMIC_RELEASE) -#define atomic64_xchg_relaxed(obj, val) ATOMIC_FUNC(exchange, 8)(obj, val, __ATOMIC_RELAXED) +#define atomic_set(obj, val) atomic_store_4(obj, val, __ATOMIC_RELAXED) +#define atomic_set_release(obj, val) atomic_store_4(obj, val, __ATOMIC_RELEASE) +#define atomic64_set(obj, val) atomic_store_8(obj, val, __ATOMIC_RELAXED) +#define atomic64_set_release(obj, val) atomic_store_8(obj, val, __ATOMIC_RELEASE) + +#define atomic_read(obj) atomic_load_4(obj, __ATOMIC_RELAXED) +#define atomic_read_acquire(obj) atomic_load_4(obj, __ATOMIC_ACQUIRE) +#define atomic64_read(obj) atomic_load_8(obj, __ATOMIC_RELAXED) +#define atomic64_read_acquire(obj) atomic_load_8(obj, __ATOMIC_ACQUIRE) + +#define atomic_add(obj, val) atomic_fetch_add_4(obj, val, __ATOMIC_ACQ_REL) +#define atomic_add_acquire(obj, val) atomic_fetch_add_4(obj, val, __ATOMIC_ACQUIRE) +#define atomic_add_release(obj, val) atomic_fetch_add_4(obj, val, __ATOMIC_RELEASE) +#define atomic_add_relaxed(obj, val) atomic_fetch_add_4(obj, val, __ATOMIC_RELAXED) +#define atomic64_add(obj, val) atomic_fetch_add_8(obj, val, __ATOMIC_ACQ_REL) +#define atomic64_add_acquire(obj, val) atomic_fetch_add_8(obj, val, __ATOMIC_ACQUIRE) +#define atomic64_add_release(obj, val) atomic_fetch_add_8(obj, val, __ATOMIC_RELEASE) +#define atomic64_add_relaxed(obj, val) atomic_fetch_add_8(obj, val, __ATOMIC_RELAXED) + +#define atomic_sub(obj, val) atomic_fetch_sub_4(obj, val, __ATOMIC_ACQ_REL) +#define atomic_sub_acquire(obj, val) atomic_fetch_sub_4(obj, val, __ATOMIC_ACQUIRE) +#define atomic_sub_release(obj, val) atomic_fetch_sub_4(obj, val, __ATOMIC_RELEASE) +#define atomic_sub_relaxed(obj, val) atomic_fetch_sub_4(obj, val, __ATOMIC_RELAXED) +#define atomic64_sub(obj, val) atomic_fetch_sub_8(obj, val, __ATOMIC_ACQ_REL) +#define atomic64_sub_acquire(obj, val) atomic_fetch_sub_8(obj, val, __ATOMIC_ACQUIRE) +#define atomic64_sub_release(obj, val) atomic_fetch_sub_8(obj, val, __ATOMIC_RELEASE) +#define atomic64_sub_relaxed(obj, val) atomic_fetch_sub_8(obj, val, __ATOMIC_RELAXED) + +#define atomic_and(obj, val) atomic_fetch_and_4(obj, val, __ATOMIC_ACQ_REL) +#define atomic_and_acquire(obj, val) atomic_fetch_and_4(obj, val, __ATOMIC_ACQUIRE) +#define atomic_and_release(obj, val) atomic_fetch_and_4(obj, val, __ATOMIC_RELEASE) +#define atomic_and_relaxed(obj, val) atomic_fetch_and_4(obj, val, __ATOMIC_RELAXED) +#define atomic64_and(obj, val) atomic_fetch_and_8(obj, val, __ATOMIC_ACQ_REL) +#define atomic64_and_acquire(obj, val) atomic_fetch_and_8(obj, val, __ATOMIC_ACQUIRE) +#define atomic64_and_release(obj, val) atomic_fetch_and_8(obj, val, __ATOMIC_RELEASE) +#define atomic64_and_relaxed(obj, val) atomic_fetch_and_8(obj, val, __ATOMIC_RELAXED) + +#define atomic_or(obj, val) atomic_fetch_or_4(obj, val, __ATOMIC_ACQ_REL) +#define atomic_or_acquire(obj, val) atomic_fetch_or_4(obj, val, __ATOMIC_ACQUIRE) +#define atomic_or_release(obj, val) atomic_fetch_or_4(obj, val, __ATOMIC_RELEASE) +#define atomic_or_relaxed(obj, val) atomic_fetch_or_4(obj, val, __ATOMIC_RELAXED) +#define atomic64_or(obj, val) atomic_fetch_or_8(obj, val, __ATOMIC_ACQ_REL) +#define atomic64_or_acquire(obj, val) atomic_fetch_or_8(obj, val, __ATOMIC_ACQUIRE) +#define atomic64_or_release(obj, val) atomic_fetch_or_8(obj, val, __ATOMIC_RELEASE) +#define atomic64_or_relaxed(obj, val) atomic_fetch_or_8(obj, val, __ATOMIC_RELAXED) + +#define atomic_xor(obj, val) atomic_fetch_xor_4(obj, val, __ATOMIC_ACQ_REL) +#define atomic_xor_acquire(obj, val) atomic_fetch_xor_4(obj, val, __ATOMIC_ACQUIRE) +#define atomic_xor_release(obj, val) atomic_fetch_xor_4(obj, val, __ATOMIC_RELEASE) +#define atomic_xor_relaxed(obj, val) atomic_fetch_xor_4(obj, val, __ATOMIC_RELAXED) +#define atomic64_xor(obj, val) atomic_fetch_xor_8(obj, val, __ATOMIC_ACQ_REL) +#define atomic64_xor_acquire(obj, val) atomic_fetch_xor_8(obj, val, __ATOMIC_ACQUIRE) +#define atomic64_xor_release(obj, val) atomic_fetch_xor_8(obj, val, __ATOMIC_RELEASE) +#define atomic64_xor_relaxed(obj, val) atomic_fetch_xor_8(obj, val, __ATOMIC_RELAXED) + +#define atomic_xchg(obj, val) atomic_exchange_4(obj, val, __ATOMIC_ACQ_REL) +#define atomic_xchg_acquire(obj, val) atomic_exchange_4(obj, val, __ATOMIC_ACQUIRE) +#define atomic_xchg_release(obj, val) atomic_exchange_4(obj, val, __ATOMIC_RELEASE) +#define atomic_xchg_relaxed(obj, val) atomic_exchange_4(obj, val, __ATOMIC_RELAXED) +#define atomic64_xchg(obj, val) atomic_exchange_8(obj, val, __ATOMIC_ACQ_REL) +#define atomic64_xchg_acquire(obj, val) atomic_exchange_8(obj, val, __ATOMIC_ACQUIRE) +#define atomic64_xchg_release(obj, val) atomic_exchange_8(obj, val, __ATOMIC_RELEASE) +#define atomic64_xchg_relaxed(obj, val) atomic_exchange_8(obj, val, __ATOMIC_RELAXED) #define atomic_cmpxchg(obj, expected, desired) \ - ATOMIC_FUNC(compare_exchange_strong, 4)(obj, (FAR int32_t *)expected, desired, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED) + atomic_compare_exchange_4(obj, (FAR int32_t *)expected, desired, false, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED) #define atomic_cmpxchg_acquire(obj, expected, desired) \ - ATOMIC_FUNC(compare_exchange_strong, 4)(obj, (FAR int32_t *)expected, desired, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED) + atomic_compare_exchange_4(obj, (FAR int32_t *)expected, desired, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED) #define atomic_cmpxchg_release(obj, expected, desired) \ - ATOMIC_FUNC(compare_exchange_strong, 4)(obj, (FAR int32_t *)expected, desired, __ATOMIC_RELEASE, __ATOMIC_RELAXED) + atomic_compare_exchange_4(obj, (FAR int32_t *)expected, desired, false, __ATOMIC_RELEASE, __ATOMIC_RELAXED) #define atomic_cmpxchg_relaxed(obj, expected, desired) \ - ATOMIC_FUNC(compare_exchange_strong, 4)(obj, (FAR int32_t *)expected, desired, __ATOMIC_RELAXED, __ATOMIC_RELAXED) - -#define atomic_try_cmpxchg(obj, expected, desired) \ - ATOMIC_FUNC(compare_exchange_weak, 4)(obj, (FAR int32_t *)expected, desired, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED) -#define atomic_try_cmpxchg_acquire(obj, expected, desired) \ - ATOMIC_FUNC(compare_exchange_weak, 4)(obj, (FAR int32_t *)expected, desired, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED) -#define atomic_try_cmpxchg_release(obj, expected, desired) \ - ATOMIC_FUNC(compare_exchange_weak, 4)(obj, (FAR int32_t *)expected, desired, __ATOMIC_RELEASE, __ATOMIC_RELAXED) -#define atomic_try_cmpxchg_relaxed(obj, expected, desired) \ - ATOMIC_FUNC(compare_exchange_weak, 4)(obj, (FAR int32_t *)expected, desired, __ATOMIC_RELAXED, __ATOMIC_RELAXED) - + atomic_compare_exchange_4(obj, (FAR int32_t *)expected, desired, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED) #define atomic64_cmpxchg(obj, expected, desired) \ - ATOMIC_FUNC(compare_exchange_strong, 8)(obj, (FAR int64_t *)expected, desired, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED) + atomic_compare_exchange_8(obj, (FAR int64_t *)expected, desired, false, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED) #define atomic64_cmpxchg_acquire(obj, expected, desired) \ - ATOMIC_FUNC(compare_exchange_strong, 8)(obj, (FAR int64_t *)expected, desired, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED) + atomic_compare_exchange_8(obj, (FAR int64_t *)expected, desired, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED) #define atomic64_cmpxchg_release(obj, expected, desired) \ - ATOMIC_FUNC(compare_exchange_strong, 8)(obj, (FAR int64_t *)expected, desired, __ATOMIC_RELEASE, __ATOMIC_RELAXED) + atomic_compare_exchange_8(obj, (FAR int64_t *)expected, desired, false, __ATOMIC_RELEASE, __ATOMIC_RELAXED) #define atomic64_cmpxchg_relaxed(obj, expected, desired) \ - ATOMIC_FUNC(compare_exchange_strong, 8)(obj, (FAR int64_t *)expected, desired, __ATOMIC_RELAXED, __ATOMIC_RELAXED) + atomic_compare_exchange_8(obj, (FAR int64_t *)expected, desired, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED) +#define atomic_try_cmpxchg(obj, expected, desired) \ + atomic_compare_exchange_4(obj, (FAR int32_t *)expected, desired, true, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED) +#define atomic_try_cmpxchg_acquire(obj, expected, desired) \ + atomic_compare_exchange_4(obj, (FAR int32_t *)expected, desired, true, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED) +#define atomic_try_cmpxchg_release(obj, expected, desired) \ + atomic_compare_exchange_4(obj, (FAR int32_t *)expected, desired, true, __ATOMIC_RELEASE, __ATOMIC_RELAXED) +#define atomic_try_cmpxchg_relaxed(obj, expected, desired) \ + atomic_compare_exchange_4(obj, (FAR int32_t *)expected, desired, true, __ATOMIC_RELAXED, __ATOMIC_RELAXED) #define atomic64_try_cmpxchg(obj, expected, desired) \ - ATOMIC_FUNC(compare_exchange_weak, 8)(obj, (FAR int64_t *)expected, desired, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED) + atomic_compare_exchange_8(obj, (FAR int64_t *)expected, desired, true, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED) #define atomic64_try_cmpxchg_acquire(obj, expected, desired) \ - ATOMIC_FUNC(compare_exchange_weak, 8)(obj, (FAR int64_t *)expected, desired, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED) + atomic_compare_exchange_8(obj, (FAR int64_t *)expected, desired, true, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED) #define atomic64_try_cmpxchg_release(obj, expected, desired) \ - ATOMIC_FUNC(compare_exchange_weak, 8)(obj, (FAR int64_t *)expected, desired, __ATOMIC_RELEASE, __ATOMIC_RELAXED) + atomic_compare_exchange_8(obj, (FAR int64_t *)expected, desired, true, __ATOMIC_RELEASE, __ATOMIC_RELAXED) #define atomic64_try_cmpxchg_relaxed(obj, expected, desired) \ - ATOMIC_FUNC(compare_exchange_weak, 8)(obj, (FAR int64_t *)expected, desired, __ATOMIC_RELAXED, __ATOMIC_RELAXED) + atomic_compare_exchange_8(obj, (FAR int64_t *)expected, desired, true, __ATOMIC_RELAXED, __ATOMIC_RELAXED) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef volatile int32_t atomic_t; +typedef volatile int64_t atomic64_t; -#endif /**************************************************************************** * Public Function Prototypes @@ -239,40 +176,44 @@ extern "C" #define EXTERN extern #endif -void nx_atomic_store_4(FAR volatile void *ptr, int32_t value, int memorder); -void nx_atomic_store_8(FAR volatile void *ptr, int64_t value, int memorder); -int32_t nx_atomic_load_4(FAR const volatile void *ptr, int memorder); -int64_t nx_atomic_load_8(FAR const volatile void *ptr, int memorder); -int32_t nx_atomic_exchange_4(FAR volatile void *ptr, int32_t value, - int memorder); -int64_t nx_atomic_exchange_8(FAR volatile void *ptr, int64_t value, - int memorder); -bool nx_atomic_compare_exchange_4(FAR volatile void *ptr, FAR void *expect, - int32_t desired, bool weak, - int success, int failure); -bool nx_atomic_compare_exchange_8(FAR volatile void *ptr, FAR void *expect, - int64_t desired, bool weak, - int success, int failure); -int32_t nx_atomic_fetch_add_4(FAR volatile void *ptr, int32_t value, - int memorder); -int64_t nx_atomic_fetch_add_8(FAR volatile void *ptr, int64_t value, - int memorder); -int32_t nx_atomic_fetch_sub_4(FAR volatile void *ptr, int32_t value, - int memorder); -int64_t nx_atomic_fetch_sub_8(FAR volatile void *ptr, int64_t value, - int memorder); -int32_t nx_atomic_fetch_and_4(FAR volatile void *ptr, int32_t value, - int memorder); -int64_t nx_atomic_fetch_and_8(FAR volatile void *ptr, int64_t value, - int memorder); -int32_t nx_atomic_fetch_or_4(FAR volatile void *ptr, int32_t value, - int memorder); -int64_t nx_atomic_fetch_or_8(FAR volatile void *ptr, int64_t value, - int memorder); -int32_t nx_atomic_fetch_xor_4(FAR volatile void *ptr, int32_t value, - int memorder); -int64_t nx_atomic_fetch_xor_8(FAR volatile void *ptr, int64_t value, - int memorder); +#ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN +void atomic_store_4(FAR volatile void *ptr, int32_t value, int memorder); +void atomic_store_8(FAR volatile void *ptr, int64_t value, int memorder); +int32_t atomic_load_4(FAR const volatile void *ptr, int memorder); +int64_t atomic_load_8(FAR const volatile void *ptr, int memorder); +int32_t atomic_exchange_4(FAR volatile void *ptr, int32_t value, + int memorder); +int64_t atomic_exchange_8(FAR volatile void *ptr, int64_t value, + int memorder); +bool atomic_compare_exchange_4(FAR volatile void *ptr, + FAR volatile void *expect, + int32_t desired, bool weak, + int success, int failure); +bool atomic_compare_exchange_8(FAR volatile void *ptr, + FAR volatile void *expect, + int64_t desired, bool weak, + int success, int failure); +int32_t atomic_fetch_add_4(FAR volatile void *ptr, int32_t value, + int memorder); +int64_t atomic_fetch_add_8(FAR volatile void *ptr, int64_t value, + int memorder); +int32_t atomic_fetch_sub_4(FAR volatile void *ptr, int32_t value, + int memorder); +int64_t atomic_fetch_sub_8(FAR volatile void *ptr, int64_t value, + int memorder); +int32_t atomic_fetch_and_4(FAR volatile void *ptr, int32_t value, + int memorder); +int64_t atomic_fetch_and_8(FAR volatile void *ptr, int64_t value, + int memorder); +int32_t atomic_fetch_or_4(FAR volatile void *ptr, int32_t value, + int memorder); +int64_t atomic_fetch_or_8(FAR volatile void *ptr, int64_t value, + int memorder); +int32_t atomic_fetch_xor_4(FAR volatile void *ptr, int32_t value, + int memorder); +int64_t atomic_fetch_xor_8(FAR volatile void *ptr, int64_t value, + int memorder); +#endif #undef EXTERN #if defined(__cplusplus) diff --git a/libs/libc/machine/arch_atomic64.c b/libs/libc/machine/arch_atomic64.c index 5b222915fdbf0..41cdeafeaf0a3 100644 --- a/libs/libc/machine/arch_atomic64.c +++ b/libs/libc/machine/arch_atomic64.c @@ -60,7 +60,7 @@ static inline void atomic_unlock(irqstate_t flags) STORE(__atomic_store_, 8, uint64_t) #ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN -STORE(nx_atomic_store_, 8, int64_t) +STORE(atomic_store_, 8, int64_t) #endif /**************************************************************************** @@ -69,7 +69,7 @@ STORE(nx_atomic_store_, 8, int64_t) LOAD(__atomic_load_, 8, uint64_t) #ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN -LOAD(nx_atomic_load_, 8, int64_t) +LOAD(atomic_load_, 8, int64_t) #endif /**************************************************************************** @@ -78,7 +78,7 @@ LOAD(nx_atomic_load_, 8, int64_t) EXCHANGE(__atomic_exchange_, 8, uint64_t) #ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN -EXCHANGE(nx_atomic_exchange_, 8, int64_t) +EXCHANGE(atomic_exchange_, 8, int64_t) #endif /**************************************************************************** @@ -87,7 +87,7 @@ EXCHANGE(nx_atomic_exchange_, 8, int64_t) CMP_EXCHANGE(__atomic_compare_exchange_, 8, uint64_t) #ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN -CMP_EXCHANGE(nx_atomic_compare_exchange_, 8, int64_t) +CMP_EXCHANGE(atomic_compare_exchange_, 8, int64_t) #endif /**************************************************************************** @@ -96,7 +96,7 @@ CMP_EXCHANGE(nx_atomic_compare_exchange_, 8, int64_t) FLAG_TEST_AND_SET(__atomic_flags_test_and_set_, 8, uint64_t) #ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN -FLAG_TEST_AND_SET(nx_atomic_flags_test_and_set_, 8, int64_t) +FLAG_TEST_AND_SET(atomic_flags_test_and_set_, 8, int64_t) #endif /**************************************************************************** @@ -105,7 +105,7 @@ FLAG_TEST_AND_SET(nx_atomic_flags_test_and_set_, 8, int64_t) FETCH_ADD(__atomic_fetch_add_, 8, uint64_t) #ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN -FETCH_ADD(nx_atomic_fetch_add_, 8, int64_t) +FETCH_ADD(atomic_fetch_add_, 8, int64_t) #endif /**************************************************************************** @@ -114,7 +114,7 @@ FETCH_ADD(nx_atomic_fetch_add_, 8, int64_t) FETCH_SUB(__atomic_fetch_sub_, 8, uint64_t) #ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN -FETCH_SUB(nx_atomic_fetch_sub_, 8, int64_t) +FETCH_SUB(atomic_fetch_sub_, 8, int64_t) #endif /**************************************************************************** @@ -123,7 +123,7 @@ FETCH_SUB(nx_atomic_fetch_sub_, 8, int64_t) FETCH_AND(__atomic_fetch_and_, 8, uint64_t) #ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN -FETCH_AND(nx_atomic_fetch_and_, 8, int64_t) +FETCH_AND(atomic_fetch_and_, 8, int64_t) #endif /**************************************************************************** @@ -132,7 +132,7 @@ FETCH_AND(nx_atomic_fetch_and_, 8, int64_t) FETCH_OR(__atomic_fetch_or_, 8, uint64_t) #ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN -FETCH_OR(nx_atomic_fetch_or_, 8, int64_t) +FETCH_OR(atomic_fetch_or_, 8, int64_t) #endif /**************************************************************************** @@ -141,7 +141,7 @@ FETCH_OR(nx_atomic_fetch_or_, 8, int64_t) FETCH_XOR(__atomic_fetch_xor_, 8, uint64_t) #ifndef CONFIG_LIBC_ATOMIC_TOOLCHAIN -FETCH_XOR(nx_atomic_fetch_xor_, 8, int64_t) +FETCH_XOR(atomic_fetch_xor_, 8, int64_t) #endif /* Clang define the __sync builtins, add #ifndef to avoid diff --git a/libs/libc/machine/arch_atomic_irq.c b/libs/libc/machine/arch_atomic_irq.c index 4a50d0aa2fbb9..483d7b1fed385 100644 --- a/libs/libc/machine/arch_atomic_irq.c +++ b/libs/libc/machine/arch_atomic_irq.c @@ -68,7 +68,7 @@ STORE(__atomic_store_, 2, uint16_t) ****************************************************************************/ STORE(__atomic_store_, 4, uint32_t) -STORE(nx_atomic_store_, 4, int32_t) +STORE(atomic_store_, 4, int32_t) /**************************************************************************** * Name: __atomic_load_1 @@ -87,7 +87,7 @@ LOAD(__atomic_load_, 2, uint16_t) ****************************************************************************/ LOAD(__atomic_load_, 4, uint32_t) -LOAD(nx_atomic_load_, 4, int32_t) +LOAD(atomic_load_, 4, int32_t) /**************************************************************************** * Name: __atomic_exchange_1 @@ -106,7 +106,7 @@ EXCHANGE(__atomic_exchange_, 2, uint16_t) ****************************************************************************/ EXCHANGE(__atomic_exchange_, 4, uint32_t) -EXCHANGE(nx_atomic_exchange_, 4, int32_t) +EXCHANGE(atomic_exchange_, 4, int32_t) /**************************************************************************** * Name: __atomic_compare_exchange_1 @@ -125,7 +125,7 @@ CMP_EXCHANGE(__atomic_compare_exchange_, 2, uint16_t) ****************************************************************************/ CMP_EXCHANGE(__atomic_compare_exchange_, 4, uint32_t) -CMP_EXCHANGE(nx_atomic_compare_exchange_, 4, int32_t) +CMP_EXCHANGE(atomic_compare_exchange_, 4, int32_t) /**************************************************************************** * Name: __atomic_flag_test_and_set_1 @@ -144,7 +144,7 @@ FLAG_TEST_AND_SET(__atomic_flags_test_and_set_, 2, uint16_t) ****************************************************************************/ FLAG_TEST_AND_SET(__atomic_flags_test_and_set_, 4, uint32_t) -FLAG_TEST_AND_SET(nx_atomic_flags_test_and_set_, 4, int32_t) +FLAG_TEST_AND_SET(atomic_flags_test_and_set_, 4, int32_t) /**************************************************************************** * Name: __atomic_fetch_add_1 @@ -163,7 +163,7 @@ FETCH_ADD(__atomic_fetch_add_, 2, uint16_t) ****************************************************************************/ FETCH_ADD(__atomic_fetch_add_, 4, uint32_t) -FETCH_ADD(nx_atomic_fetch_add_, 4, int32_t) +FETCH_ADD(atomic_fetch_add_, 4, int32_t) /**************************************************************************** * Name: __atomic_fetch_sub_1 @@ -182,7 +182,7 @@ FETCH_SUB(__atomic_fetch_sub_, 2, uint16_t) ****************************************************************************/ FETCH_SUB(__atomic_fetch_sub_, 4, uint32_t) -FETCH_SUB(nx_atomic_fetch_sub_, 4, int32_t) +FETCH_SUB(atomic_fetch_sub_, 4, int32_t) /**************************************************************************** * Name: __atomic_fetch_and_1 @@ -201,7 +201,7 @@ FETCH_AND(__atomic_fetch_and_, 2, uint16_t) ****************************************************************************/ FETCH_AND(__atomic_fetch_and_, 4, uint32_t) -FETCH_AND(nx_atomic_fetch_and_, 4, int32_t) +FETCH_AND(atomic_fetch_and_, 4, int32_t) /**************************************************************************** * Name: __atomic_fetch_or_1 @@ -220,7 +220,7 @@ FETCH_OR(__atomic_fetch_or_, 2, uint16_t) ****************************************************************************/ FETCH_OR(__atomic_fetch_or_, 4, uint32_t) -FETCH_OR(nx_atomic_fetch_or_, 4, int32_t) +FETCH_OR(atomic_fetch_or_, 4, int32_t) /**************************************************************************** * Name: __atomic_fetch_xor_1 @@ -239,7 +239,7 @@ FETCH_XOR(__atomic_fetch_xor_, 2, uint16_t) ****************************************************************************/ FETCH_XOR(__atomic_fetch_xor_, 4, uint32_t) -FETCH_XOR(nx_atomic_fetch_xor_, 4, int32_t) +FETCH_XOR(atomic_fetch_xor_, 4, int32_t) /* Clang define the __sync builtins, add #ifndef to avoid * redefined/redeclared problem. diff --git a/libs/libc/machine/tricore/arch_atomic.c b/libs/libc/machine/tricore/arch_atomic.c index 7f10fa0f07902..970f90e6e108f 100644 --- a/libs/libc/machine/tricore/arch_atomic.c +++ b/libs/libc/machine/tricore/arch_atomic.c @@ -89,7 +89,7 @@ \ do \ { \ - old_val = nx_atomic_load_4(ptr, memorder); \ + old_val = atomic_load_4(ptr, memorder); \ } \ while (__cmpAndSwap(ptr, old_val + value, old_val) != old_val); \ \ @@ -104,7 +104,7 @@ \ do \ { \ - old_val = nx_atomic_load_4(ptr, memorder); \ + old_val = atomic_load_4(ptr, memorder); \ } \ while (__cmpAndSwap(ptr, old_val - value, old_val) != old_val); \ \ @@ -119,7 +119,7 @@ \ do \ { \ - old_val = nx_atomic_load_4(ptr, memorder); \ + old_val = atomic_load_4(ptr, memorder); \ } \ while (__cmpAndSwap(ptr, old_val & value, old_val) != old_val); \ \ @@ -134,7 +134,7 @@ \ do \ { \ - old_val = nx_atomic_load_4(ptr, memorder); \ + old_val = atomic_load_4(ptr, memorder); \ } \ while (__cmpAndSwap(ptr, old_val | value, old_val) != old_val); \ \ @@ -149,7 +149,7 @@ \ do \ { \ - old_val = nx_atomic_load_4(ptr, memorder); \ + old_val = atomic_load_4(ptr, memorder); \ } \ while (__cmpAndSwap(ptr, old_val ^ value, old_val) != old_val); \ \ @@ -165,67 +165,67 @@ ****************************************************************************/ ARCH_ATOMIC_STORE_4(__atomic_store_4) -ARCH_ATOMIC_STORE_4(nx_atomic_store_4) +ARCH_ATOMIC_STORE_4(atomic_store_4) /**************************************************************************** * Name: atomic_load_4 ****************************************************************************/ ARCH_ATOMIC_LOAD_4(__atomic_load_4) -ARCH_ATOMIC_LOAD_4(nx_atomic_load_4) +ARCH_ATOMIC_LOAD_4(atomic_load_4) /**************************************************************************** * Name: atomic_exchange_4 ****************************************************************************/ ARCH_ATOMIC_EXCHANGE_4(__atomic_exchange_4) -ARCH_ATOMIC_EXCHANGE_4(nx_atomic_exchange_4) +ARCH_ATOMIC_EXCHANGE_4(atomic_exchange_4) /**************************************************************************** * Name: atomic_compare_exchange_4 ****************************************************************************/ ARCH_ATOMIC_COMPARE_EXCHANGE_4(__atomic_compare_exchange_4) -ARCH_ATOMIC_COMPARE_EXCHANGE_4(nx_atomic_compare_exchange_4) +ARCH_ATOMIC_COMPARE_EXCHANGE_4(atomic_compare_exchange_4) /**************************************************************************** * Name: atomic_flag_test_and_set_4 ****************************************************************************/ ARCH_ATOMIC_FLAGS_TEST_AND_SET_4(__atomic_flags_test_and_set_4) -ARCH_ATOMIC_FLAGS_TEST_AND_SET_4(nx_atomic_flags_test_and_set_4) +ARCH_ATOMIC_FLAGS_TEST_AND_SET_4(atomic_flags_test_and_set_4) /**************************************************************************** * Name: atomic_fetch_add_4 ****************************************************************************/ ARCH_ATOMIC_FETCH_ADD_4(__atomic_fetch_add_4) -ARCH_ATOMIC_FETCH_ADD_4(nx_atomic_fetch_add_4) +ARCH_ATOMIC_FETCH_ADD_4(atomic_fetch_add_4) /**************************************************************************** * Name: atomic_fetch_sub_4 ****************************************************************************/ ARCH_ATOMIC_FETCH_SUB_4(__atomic_fetch_sub_4) -ARCH_ATOMIC_FETCH_SUB_4(nx_atomic_fetch_sub_4) +ARCH_ATOMIC_FETCH_SUB_4(atomic_fetch_sub_4) /**************************************************************************** * Name: atomic_fetch_and_4 ****************************************************************************/ ARCH_ATOMIC_FETCH_AND_4(__atomic_fetch_and_4) -ARCH_ATOMIC_FETCH_AND_4(nx_atomic_fetch_and_4) +ARCH_ATOMIC_FETCH_AND_4(atomic_fetch_and_4) /**************************************************************************** * Name: atomic_fetch_or_4 ****************************************************************************/ ARCH_ATOMIC_FETCH_OR_4(__atomic_fetch_or_4) -ARCH_ATOMIC_FETCH_OR_4(nx_atomic_fetch_or_4) +ARCH_ATOMIC_FETCH_OR_4(atomic_fetch_or_4) /**************************************************************************** * Name: atomic_fetch_xor_4 ****************************************************************************/ ARCH_ATOMIC_FETCH_XOR_4(__atomic_fetch_xor_4) -ARCH_ATOMIC_FETCH_XOR_4(nx_atomic_fetch_xor_4) +ARCH_ATOMIC_FETCH_XOR_4(atomic_fetch_xor_4) From dd6857fffe731794735a42cebb4fccf65c8d3658 Mon Sep 17 00:00:00 2001 From: zhangyu117 Date: Wed, 12 Aug 2026 15:28:17 +0800 Subject: [PATCH 09/14] nuttx/atomic: replace atomic_fetch_xxx with atomic_xxx just like zephyr Rename atomic_fetch_add/sub/or/and/xor to atomic_add/sub/or/and/xor to avoid conflicts with the C/C++ standard library naming. The atomic_fetch_xxx naming is reserved by the standard; keeping it causes function name conflicts when source files indirectly include both and /. Signed-off-by: zhangyu117 --- arch/arm/src/armv7-a/arm_gicv2.c | 2 +- arch/arm/src/rtl8720c/amebaz_depend.c | 2 +- arch/arm64/src/imx9/imx9_scmi.c | 2 +- arch/sim/src/sim/sim_ummheap.c | 8 ++++---- drivers/i3c/master.c | 4 ++-- drivers/net/netdev_upperhalf.c | 12 ++++++------ drivers/note/notesnap_driver.c | 2 +- drivers/reset/core.c | 12 ++++++------ drivers/rpmsg/rpmsg.c | 4 ++-- drivers/rpmsg/rpmsg_port.c | 4 ++-- drivers/rpmsg/rpmsg_port_spi.c | 2 +- drivers/rpmsg/rpmsg_port_spi_slave.c | 2 +- drivers/wireless/bluetooth/bt_bridge.c | 6 +++--- fs/event/event_close.c | 2 +- fs/event/event_open.c | 2 +- fs/inode/fs_files.c | 8 ++++---- fs/inode/fs_inodeaddref.c | 2 +- fs/inode/fs_inodefind.c | 2 +- fs/inode/fs_inoderelease.c | 2 +- fs/inode/fs_inoderemove.c | 2 +- fs/mount/fs_mount.c | 4 ++-- fs/mount/fs_umount2.c | 2 +- fs/mqueue/mq_open.c | 2 +- fs/semaphore/sem_close.c | 2 +- fs/semaphore/sem_open.c | 2 +- fs/shm/shm_open.c | 2 +- fs/vfs/fs_dir.c | 4 ++-- fs/vfs/fs_open.c | 2 +- fs/vfs/fs_profile.c | 4 ++-- fs/vfs/fs_pseudofile.c | 2 +- include/nuttx/spinlock.h | 6 +++--- libs/libc/misc/lib_tempbuffer.c | 2 +- libs/libc/pthread/pthread_condclockwait.c | 2 +- libs/libc/pthread/pthread_condwait.c | 2 +- sched/addrenv/addrenv.c | 4 ++-- sched/semaphore/sem_holder.c | 2 +- sched/semaphore/sem_post.c | 2 +- sched/semaphore/sem_recover.c | 4 ++-- sched/semaphore/sem_trywait.c | 2 +- sched/semaphore/sem_wait.c | 6 +++--- sched/semaphore/sem_waitirq.c | 4 ++-- wireless/bluetooth/bt_atomic.h | 12 ++++++------ 42 files changed, 78 insertions(+), 78 deletions(-) diff --git a/arch/arm/src/armv7-a/arm_gicv2.c b/arch/arm/src/armv7-a/arm_gicv2.c index 03ad226ba94ac..c6cfccec0b356 100644 --- a/arch/arm/src/armv7-a/arm_gicv2.c +++ b/arch/arm/src/armv7-a/arm_gicv2.c @@ -72,7 +72,7 @@ static atomic_t g_gic_init_done; #if defined(CONFIG_SMP) && CONFIG_SMP_NCPUS > 1 static void arm_gic_init_done(void) { - atomic_fetch_or(&g_gic_init_done, 1 << this_cpu()); + atomic_or(&g_gic_init_done, 1 << this_cpu()); } static void arm_gic_wait_done(cpu_set_t cpuset) diff --git a/arch/arm/src/rtl8720c/amebaz_depend.c b/arch/arm/src/rtl8720c/amebaz_depend.c index ac81473c3dc25..674924a5ba2c8 100644 --- a/arch/arm/src/rtl8720c/amebaz_depend.c +++ b/arch/arm/src/rtl8720c/amebaz_depend.c @@ -876,7 +876,7 @@ static void *device_mutex[5]; static void device_mutex_init(uint32_t device) { irqstate_t status; - if (atomic_fetch_or(&mutex_init, (1 << device)) & (1 << device) == 0) + if (atomic_or(&mutex_init, (1 << device)) & (1 << device) == 0) { rtw_mutex_init(&device_mutex[device]); } diff --git a/arch/arm64/src/imx9/imx9_scmi.c b/arch/arm64/src/imx9/imx9_scmi.c index 9f78831612e70..a0da93706f9d0 100644 --- a/arch/arm64/src/imx9/imx9_scmi.c +++ b/arch/arm64/src/imx9/imx9_scmi.c @@ -476,7 +476,7 @@ static int imx9_scmi_tx(uint32_t channel, uint32_t protocol_id, *header = SCMI_HEADER_MSG(message_id) | SCMI_HEADER_PROTOCOL(protocol_id) | SCMI_HEADER_TYPE(0UL) - | SCMI_HEADER_TOKEN(atomic_fetch_add(&g_token, 1)); + | SCMI_HEADER_TOKEN(atomic_add(&g_token, 1)); msg->header = *header; /* Send message via transport */ diff --git a/arch/sim/src/sim/sim_ummheap.c b/arch/sim/src/sim/sim_ummheap.c index 78626b538439c..6edde735e1cef 100644 --- a/arch/sim/src/sim/sim_ummheap.c +++ b/arch/sim/src/sim/sim_ummheap.c @@ -174,8 +174,8 @@ static void update_stats(struct mm_heap_s *heap, void *mem, size_t size, list_add_tail(&heap->alloclist, &node->node); spin_unlock_irqrestore(&heap->lock, flags); - atomic_fetch_add(&heap->aordblks, 1); - atomic_fetch_add(&heap->uordblks, size); + atomic_add(&heap->aordblks, 1); + atomic_add(&heap->uordblks, size); usmblks = atomic_read(&heap->usmblks); do { @@ -189,8 +189,8 @@ static void update_stats(struct mm_heap_s *heap, void *mem, size_t size, list_delete(&node->node); spin_unlock_irqrestore(&heap->lock, flags); - atomic_fetch_sub(&heap->aordblks, 1); - atomic_fetch_sub(&heap->uordblks, size); + atomic_sub(&heap->aordblks, 1); + atomic_sub(&heap->uordblks, size); } } diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index dfc73eafd43e5..f4038cf748145 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c @@ -1180,7 +1180,7 @@ static void i3c_master_handle_ibi(FAR void *arg) } master->ops->recycle_ibi_slot(dev, slot); - atomic_fetch_sub(&dev->ibi->pending_ibis, 1); + atomic_sub(&dev->ibi->pending_ibis, 1); if (!atomic_read(&dev->ibi->pending_ibis)) { sem_post(&dev->ibi->all_ibis_handled); @@ -1800,7 +1800,7 @@ int i3c_master_add_i3c_dev_locked(FAR struct i3c_master_controller *master, void i3c_master_queue_ibi(FAR struct i3c_dev_desc *dev, FAR struct i3c_ibi_slot *slot) { - atomic_fetch_add(&dev->ibi->pending_ibis, 1); + atomic_add(&dev->ibi->pending_ibis, 1); work_queue(HPWORK, &slot->work, i3c_master_handle_ibi, slot, 0); } diff --git a/drivers/net/netdev_upperhalf.c b/drivers/net/netdev_upperhalf.c index 883ce5e7f6392..9da33fb8922bb 100644 --- a/drivers/net/netdev_upperhalf.c +++ b/drivers/net/netdev_upperhalf.c @@ -169,7 +169,7 @@ static FAR netpkt_t *netpkt_get(FAR struct net_driver_s *dev, * cases will be limited by netdev_upper_can_tx and seldom reaches here. */ - if (atomic_fetch_sub(&upper->lower->quota_ptr[type], 1) <= 0) + if (atomic_sub(&upper->lower->quota_ptr[type], 1) <= 0) { nwarn("WARNING: Allowing temporarily exceeding quota of %s.\n", dev->d_ifname); @@ -196,7 +196,7 @@ static void netpkt_put(FAR struct net_driver_s *dev, FAR netpkt_t *pkt, DEBUGASSERT(dev && pkt); - atomic_fetch_add(&upper->lower->quota_ptr[type], 1); + atomic_add(&upper->lower->quota_ptr[type], 1); netdev_iob_replace_l2(dev, pkt); } @@ -1723,9 +1723,9 @@ FAR netpkt_t *netpkt_alloc(FAR struct netdev_lowerhalf_s *dev, { FAR netpkt_t *pkt; - if (atomic_fetch_sub(&dev->quota_ptr[type], 1) <= 0) + if (atomic_sub(&dev->quota_ptr[type], 1) <= 0) { - atomic_fetch_add(&dev->quota_ptr[type], 1); + atomic_add(&dev->quota_ptr[type], 1); return NULL; } @@ -1742,7 +1742,7 @@ FAR netpkt_t *netpkt_alloc(FAR struct netdev_lowerhalf_s *dev, if (pkt == NULL) { - atomic_fetch_add(&dev->quota_ptr[type], 1); + atomic_add(&dev->quota_ptr[type], 1); return NULL; } @@ -1766,7 +1766,7 @@ FAR netpkt_t *netpkt_alloc(FAR struct netdev_lowerhalf_s *dev, void netpkt_free(FAR struct netdev_lowerhalf_s *dev, FAR netpkt_t *pkt, enum netpkt_type_e type) { - atomic_fetch_add(&dev->quota_ptr[type], 1); + atomic_add(&dev->quota_ptr[type], 1); iob_free_chain(pkt); } diff --git a/drivers/note/notesnap_driver.c b/drivers/note/notesnap_driver.c index 47762ef0e45d2..8b0aa478ad78e 100644 --- a/drivers/note/notesnap_driver.c +++ b/drivers/note/notesnap_driver.c @@ -219,7 +219,7 @@ static inline void notesnap_common(FAR struct note_driver_s *drv, /* Atomic operation, equivalent to snap.index++; */ - index = atomic_fetch_add(&snap->index, 1); + index = atomic_add(&snap->index, 1); note = &snap->buffer[index % CONFIG_DRIVERS_NOTESNAP_NBUFFERS]; note->type = type; diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 2495009ed0796..bcf88d81672f6 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -280,7 +280,7 @@ reset_control_get_internal(FAR struct reset_controller_dev *rcdev, return NULL; } - atomic_fetch_add(&rstc->refcnt, 1); + atomic_add(&rstc->refcnt, 1); return rstc; } } @@ -332,7 +332,7 @@ static void reset_control_put_internal(FAR struct reset_control *rstc) { DEBUGASSERT(nxmutex_is_locked(&g_reset_list_mutex)); - if (atomic_fetch_sub(&rstc->refcnt, 1) == 1) + if (atomic_sub(&rstc->refcnt, 1) == 1) { DEBUGASSERT(nxmutex_is_locked(&g_reset_list_mutex)); list_delete(&rstc->list); @@ -533,7 +533,7 @@ int reset_control_reset(FAR struct reset_control *rstc) return -EINVAL; } - if (atomic_fetch_add(&rstc->triggered_count, 1) != 0) + if (atomic_add(&rstc->triggered_count, 1) != 0) { return 0; } @@ -552,7 +552,7 @@ int reset_control_reset(FAR struct reset_control *rstc) if (rstc->shared && ret < 0) { - atomic_fetch_sub(&rstc->triggered_count, 1); + atomic_sub(&rstc->triggered_count, 1); } return ret; @@ -609,7 +609,7 @@ int reset_control_assert(FAR struct reset_control *rstc) return -EINVAL; } - if (atomic_fetch_sub(&rstc->deassert_count, 1) != 1) + if (atomic_sub(&rstc->deassert_count, 1) != 1) { return 0; } @@ -688,7 +688,7 @@ int reset_control_deassert(FAR struct reset_control *rstc) return -EINVAL; } - if (atomic_fetch_add(&rstc->deassert_count, 1) != 0) + if (atomic_add(&rstc->deassert_count, 1) != 0) { return 0; } diff --git a/drivers/rpmsg/rpmsg.c b/drivers/rpmsg/rpmsg.c index 217925f6a8a42..636c0b0ed5087 100644 --- a/drivers/rpmsg/rpmsg.c +++ b/drivers/rpmsg/rpmsg.c @@ -605,8 +605,8 @@ void rpmsg_modify_signals(FAR struct rpmsg_s *rpmsg, FAR struct metal_list *node; bool needlock; - atomic_fetch_and_acquire(&rpmsg->signals, ~clrflags); - atomic_fetch_or_acquire(&rpmsg->signals, setflags); + atomic_and_acquire(&rpmsg->signals, ~clrflags); + atomic_or_acquire(&rpmsg->signals, setflags); /* Send signal to Router Hub */ diff --git a/drivers/rpmsg/rpmsg_port.c b/drivers/rpmsg/rpmsg_port.c index d3e2352f00567..c37e3af5205c8 100644 --- a/drivers/rpmsg/rpmsg_port.c +++ b/drivers/rpmsg/rpmsg_port.c @@ -329,7 +329,7 @@ static void rpmsg_port_hold_rx_buffer(FAR struct rpmsg_device *rdev, { FAR struct rpmsg_hdr *rphdr = RPMSG_LOCATE_HDR(rxbuf); - atomic_fetch_add(&rphdr->reserved, 1 << RPMSG_BUF_HELD_SHIFT); + atomic_add(&rphdr->reserved, 1 << RPMSG_BUF_HELD_SHIFT); } /**************************************************************************** @@ -345,7 +345,7 @@ static void rpmsg_port_release_rx_buffer(FAR struct rpmsg_device *rdev, FAR struct rpmsg_port_header_s *hdr = metal_container_of(rphdr, struct rpmsg_port_header_s, buf); uint32_t reserved = - atomic_fetch_sub(&rphdr->reserved, 1 << RPMSG_BUF_HELD_SHIFT); + atomic_sub(&rphdr->reserved, 1 << RPMSG_BUF_HELD_SHIFT); if ((reserved & RPMSG_BUF_HELD_MASK) == (1 << RPMSG_BUF_HELD_SHIFT)) { diff --git a/drivers/rpmsg/rpmsg_port_spi.c b/drivers/rpmsg/rpmsg_port_spi.c index 8d3eea04959e3..472b66023b92f 100644 --- a/drivers/rpmsg/rpmsg_port_spi.c +++ b/drivers/rpmsg/rpmsg_port_spi.c @@ -268,7 +268,7 @@ static void rpmsg_port_spi_exchange(FAR struct rpmsg_port_spi_s *rpspi) int pending; IOEXP_WRITEPIN(rpspi->ioe, rpspi->mreq, 0); - pending = atomic_fetch_add(&rpspi->transferring, 1); + pending = atomic_add(&rpspi->transferring, 1); if (pending > 0) { if (pending > 1) diff --git a/drivers/rpmsg/rpmsg_port_spi_slave.c b/drivers/rpmsg/rpmsg_port_spi_slave.c index 1a8e0ab63fc2a..f13bf458f9830 100644 --- a/drivers/rpmsg/rpmsg_port_spi_slave.c +++ b/drivers/rpmsg/rpmsg_port_spi_slave.c @@ -243,7 +243,7 @@ static void rpmsg_port_spi_exchange(FAR struct rpmsg_port_spi_s *rpspi) { FAR struct rpmsg_port_header_s *txhdr; - if (atomic_fetch_add(&rpspi->transferring, 1)) + if (atomic_add(&rpspi->transferring, 1)) { return; } diff --git a/drivers/wireless/bluetooth/bt_bridge.c b/drivers/wireless/bluetooth/bt_bridge.c index 42fd3d2038182..0cdbc29dd9a2a 100644 --- a/drivers/wireless/bluetooth/bt_bridge.c +++ b/drivers/wireless/bluetooth/bt_bridge.c @@ -420,12 +420,12 @@ static int bt_bridge_open(FAR struct bt_driver_s *drv) FAR struct bt_bridge_s *bridge = device->bridge; FAR struct bt_driver_s *driver = bridge->driver; - if (atomic_fetch_add(&bridge->refs, 1) == 0) + if (atomic_add(&bridge->refs, 1) == 0) { int ret = driver->open(driver); if (ret < 0) { - atomic_fetch_sub(&bridge->refs, 1); + atomic_sub(&bridge->refs, 1); } return ret; @@ -514,7 +514,7 @@ static void bt_bridge_close(FAR struct bt_driver_s *drv) FAR struct bt_bridge_s *bridge = device->bridge; FAR struct bt_driver_s *driver = bridge->driver; - if (atomic_fetch_sub(&bridge->refs, 1) == 1) + if (atomic_sub(&bridge->refs, 1) == 1) { driver->close(driver); }; diff --git a/fs/event/event_close.c b/fs/event/event_close.c index c2e8cd8a4a784..4a6e61c125c11 100644 --- a/fs/event/event_close.c +++ b/fs/event/event_close.c @@ -79,7 +79,7 @@ int nxevent_close(FAR nxevent_t *event) * now. */ - if (atomic_fetch_sub(&inode->i_crefs, 1) <= 1) + if (atomic_sub(&inode->i_crefs, 1) <= 1) { nxevent_destroy(&nevent->ne_event); group_free(NULL, nevent); diff --git a/fs/event/event_open.c b/fs/event/event_open.c index 2f0b45f52b135..6781d055029dc 100644 --- a/fs/event/event_open.c +++ b/fs/event/event_open.c @@ -186,7 +186,7 @@ int nxevent_open(FAR nxevent_t **event, FAR const char *name, /* Initialize the inode */ INODE_SET_NAMEDEVENT(inode); - atomic_fetch_add(&inode->i_crefs, 1); + atomic_add(&inode->i_crefs, 1); /* Initialize the event groups */ diff --git a/fs/inode/fs_files.c b/fs/inode/fs_files.c index 4319ed502d52a..b039051bb7359 100644 --- a/fs/inode/fs_files.c +++ b/fs/inode/fs_files.c @@ -75,7 +75,7 @@ static void fdlist_get_by_index(FAR struct fdlist *list, *filep = fdp1->f_file; if (*filep != NULL) { - atomic_fetch_add(&(*filep)->f_refs, 1); + atomic_add(&(*filep)->f_refs, 1); } spin_unlock_irqrestore_notrace(&list->fl_lock, flags); @@ -605,7 +605,7 @@ int fdlist_dupfile(FAR struct fdlist *list, int oflags, int minfd, fdp = &list->fl_fds[i][j]; if (fdp->f_file == NULL) { - atomic_fetch_add(&filep->f_refs, 1); + atomic_add(&filep->f_refs, 1); fdp->f_file = filep; fdp->f_cloexec = !!(oflags & O_CLOEXEC); #ifdef CONFIG_FDSAN @@ -836,7 +836,7 @@ void file_ref(FAR struct file *filep) /* This interface is used to increase the reference count of filep */ DEBUGASSERT(filep); - atomic_fetch_add(&filep->f_refs, 1); + atomic_add(&filep->f_refs, 1); } /**************************************************************************** @@ -862,7 +862,7 @@ int file_put(FAR struct file *filep) /* If refs is zero, the close() had called, closing it now. */ - if (atomic_fetch_sub(&filep->f_refs, 1) == 1) + if (atomic_sub(&filep->f_refs, 1) == 1) { ret = file_close(filep); if (ret < 0) diff --git a/fs/inode/fs_inodeaddref.c b/fs/inode/fs_inodeaddref.c index 240c0a07b7580..2481de918e94f 100644 --- a/fs/inode/fs_inodeaddref.c +++ b/fs/inode/fs_inodeaddref.c @@ -47,6 +47,6 @@ void inode_addref(FAR struct inode *inode) { if (inode) { - atomic_fetch_add(&inode->i_crefs, 1); + atomic_add(&inode->i_crefs, 1); } } diff --git a/fs/inode/fs_inodefind.c b/fs/inode/fs_inodefind.c index f53b502b4e2f6..78cd426cf13bc 100644 --- a/fs/inode/fs_inodefind.c +++ b/fs/inode/fs_inodefind.c @@ -68,7 +68,7 @@ int inode_find(FAR struct inode_search_s *desc) /* Increment the reference count on the inode */ - atomic_fetch_add(&inode->i_crefs, 1); + atomic_add(&inode->i_crefs, 1); } inode_runlock(); diff --git a/fs/inode/fs_inoderelease.c b/fs/inode/fs_inoderelease.c index 3f9fdf346b330..584f8fd19be77 100644 --- a/fs/inode/fs_inoderelease.c +++ b/fs/inode/fs_inoderelease.c @@ -53,7 +53,7 @@ void inode_release(FAR struct inode *inode) { /* Decrement the references of the inode */ - if (atomic_fetch_sub(&inode->i_crefs, 1) <= 1) + if (atomic_sub(&inode->i_crefs, 1) <= 1) { DEBUGASSERT(inode->i_peer == NULL); inode_free(inode); diff --git a/fs/inode/fs_inoderemove.c b/fs/inode/fs_inoderemove.c index 7696bf46184c6..87c8693747931 100644 --- a/fs/inode/fs_inoderemove.c +++ b/fs/inode/fs_inoderemove.c @@ -119,7 +119,7 @@ static FAR struct inode *inode_unlink(FAR const char *path) inode->i_peer = NULL; inode->i_parent = NULL; - atomic_fetch_sub(&inode->i_crefs, 1); + atomic_sub(&inode->i_crefs, 1); } errout: diff --git a/fs/mount/fs_mount.c b/fs/mount/fs_mount.c index d46d6ee8c208e..39c87e95cdac9 100644 --- a/fs/mount/fs_mount.c +++ b/fs/mount/fs_mount.c @@ -436,7 +436,7 @@ int nx_mount(FAR const char *source, FAR const char *target, if (drvr_inode != NULL) #endif { - atomic_fetch_add(&drvr_inode->i_crefs, 1); + atomic_add(&drvr_inode->i_crefs, 1); } #endif @@ -464,7 +464,7 @@ int nx_mount(FAR const char *source, FAR const char *target, if (drvr_inode != NULL) #endif { - atomic_fetch_sub(&drvr_inode->i_crefs, 1); + atomic_sub(&drvr_inode->i_crefs, 1); } #endif diff --git a/fs/mount/fs_umount2.c b/fs/mount/fs_umount2.c index 0de3dfb16d8d3..a0cced51370fd 100644 --- a/fs/mount/fs_umount2.c +++ b/fs/mount/fs_umount2.c @@ -151,7 +151,7 @@ int nx_umount2(FAR const char *target, unsigned int flags) { /* Just decrement the reference count (without deleting it) */ - atomic_fetch_sub(&mountpt_inode->i_crefs, 1); + atomic_sub(&mountpt_inode->i_crefs, 1); inode_unlock(); } else diff --git a/fs/mqueue/mq_open.c b/fs/mqueue/mq_open.c index feeeea66761ff..798ece2e26404 100644 --- a/fs/mqueue/mq_open.c +++ b/fs/mqueue/mq_open.c @@ -337,7 +337,7 @@ static int file_mq_vopen(FAR struct file *mq, FAR const char *mq_name, /* Set the initial reference count on this inode to one */ - atomic_fetch_add(&inode->i_crefs, 1); + atomic_add(&inode->i_crefs, 1); if (created) { diff --git a/fs/semaphore/sem_close.c b/fs/semaphore/sem_close.c index da8b1c0a1740e..00078ed1bc92b 100644 --- a/fs/semaphore/sem_close.c +++ b/fs/semaphore/sem_close.c @@ -87,7 +87,7 @@ int nxsem_close(FAR sem_t *sem) * now. */ - if (atomic_fetch_sub(&inode->i_crefs, 1) <= 1) + if (atomic_sub(&inode->i_crefs, 1) <= 1) { nxsem_destroy(&nsem->ns_sem); group_free(NULL, nsem); diff --git a/fs/semaphore/sem_open.c b/fs/semaphore/sem_open.c index e89e0de746140..491e34945d285 100644 --- a/fs/semaphore/sem_open.c +++ b/fs/semaphore/sem_open.c @@ -211,7 +211,7 @@ int nxsem_open(FAR sem_t **sem, FAR const char *name, int oflags, ...) /* Initialize the inode */ INODE_SET_NAMEDSEM(inode); - atomic_fetch_add(&inode->i_crefs, 1); + atomic_add(&inode->i_crefs, 1); /* Initialize the semaphore */ diff --git a/fs/shm/shm_open.c b/fs/shm/shm_open.c index 27279c39867a5..e7db849cb9050 100644 --- a/fs/shm/shm_open.c +++ b/fs/shm/shm_open.c @@ -155,7 +155,7 @@ static int file_shm_open(FAR struct file *shm, FAR const char *name, INODE_SET_SHM(inode); inode->u.i_ops = &g_shmfs_operations; inode->i_private = NULL; - atomic_fetch_add(&inode->i_crefs, 1); + atomic_add(&inode->i_crefs, 1); } /* Associate the inode with a file structure */ diff --git a/fs/vfs/fs_dir.c b/fs/vfs/fs_dir.c index 6b93e90e7a0ca..40abdc40b1494 100644 --- a/fs/vfs/fs_dir.c +++ b/fs/vfs/fs_dir.c @@ -220,7 +220,7 @@ static off_t seek_pseudodir(FAR struct file *filep, off_t offset) { /* Increment the reference count on this next node */ - atomic_fetch_add(&curr->i_crefs, 1); + atomic_add(&curr->i_crefs, 1); } inode_unlock(); @@ -389,7 +389,7 @@ static int read_pseudodir(FAR struct fs_dirent_s *dir, { /* Increment the reference count on this next node */ - atomic_fetch_add(&pdir->next->i_crefs, 1); + atomic_add(&pdir->next->i_crefs, 1); } inode_unlock(); diff --git a/fs/vfs/fs_open.c b/fs/vfs/fs_open.c index bc2024b8a2383..82b13dec5548d 100644 --- a/fs/vfs/fs_open.c +++ b/fs/vfs/fs_open.c @@ -358,7 +358,7 @@ int file_open(FAR struct file *filep, FAR const char *path, int oflags, ...) if (ret >= OK) { - atomic_fetch_add(&filep->f_refs, 1); + atomic_add(&filep->f_refs, 1); } return ret; diff --git a/fs/vfs/fs_profile.c b/fs/vfs/fs_profile.c index 807af6df23a27..c6b1a311443ee 100644 --- a/fs/vfs/fs_profile.c +++ b/fs/vfs/fs_profile.c @@ -50,6 +50,6 @@ void fs_profile_stop(FAR clock_t *start, FAR atomic64_t *total, clock_t stop = perf_gettime(); clock_t delta = stop - *start; - atomic64_fetch_add(total, delta); - atomic_fetch_add(count, 1); + atomic64_add(total, delta); + atomic_add(count, 1); } diff --git a/fs/vfs/fs_pseudofile.c b/fs/vfs/fs_pseudofile.c index c1d8294caa9b9..db2bba68123c2 100644 --- a/fs/vfs/fs_pseudofile.c +++ b/fs/vfs/fs_pseudofile.c @@ -551,7 +551,7 @@ int pseudofile_create(FAR struct inode **node, FAR const char *path, (*node)->u.i_ops = &g_pseudofile_ops; (*node)->i_private = pf; - atomic_fetch_add(&(*node)->i_crefs, 1); + atomic_add(&(*node)->i_crefs, 1); inode_unlock(); #ifdef CONFIG_FS_NOTIFY diff --git a/include/nuttx/spinlock.h b/include/nuttx/spinlock.h index 63884365547ea..3832bad3960b7 100644 --- a/include/nuttx/spinlock.h +++ b/include/nuttx/spinlock.h @@ -183,7 +183,7 @@ static inline_function void rspin_lock_init(FAR rspinlock_t *lock) static inline_function void spin_lock_notrace(FAR volatile spinlock_t *lock) { #ifdef CONFIG_TICKET_SPINLOCK - int ticket = atomic_fetch_add(&lock->next, 1); + int ticket = atomic_add(&lock->next, 1); while (atomic_read(&lock->owner) != ticket) #else /* CONFIG_TICKET_SPINLOCK */ while (up_testset(lock) == SP_LOCKED) @@ -375,7 +375,7 @@ spin_unlock_notrace(FAR volatile spinlock_t *lock) { UP_DMB(); #ifdef CONFIG_TICKET_SPINLOCK - atomic_fetch_add(&lock->owner, 1); + atomic_add(&lock->owner, 1); #else *lock = SP_UNLOCKED; #endif @@ -1105,7 +1105,7 @@ static inline_function void read_unlock(FAR volatile rwlock_t *lock) DEBUGASSERT(atomic_read(lock) >= RW_SP_READ_LOCKED); UP_DMB(); - atomic_fetch_sub(lock, 1); + atomic_sub(lock, 1); UP_DSB(); UP_SEV(); } diff --git a/libs/libc/misc/lib_tempbuffer.c b/libs/libc/misc/lib_tempbuffer.c index 470342e52113d..f642cffa67181 100644 --- a/libs/libc/misc/lib_tempbuffer.c +++ b/libs/libc/misc/lib_tempbuffer.c @@ -140,7 +140,7 @@ void lib_put_tempbuffer(FAR char *buffer) { DEBUGASSERT((atomic_read(&g_tempbuffer.free_bitmap) & (1u << index)) == 0); - atomic_fetch_or_acquire(&g_tempbuffer.free_bitmap, 1u << index); + atomic_or_acquire(&g_tempbuffer.free_bitmap, 1u << index); return; } diff --git a/libs/libc/pthread/pthread_condclockwait.c b/libs/libc/pthread/pthread_condclockwait.c index e8e692d50ab1b..d1b899f0998d8 100644 --- a/libs/libc/pthread/pthread_condclockwait.c +++ b/libs/libc/pthread/pthread_condclockwait.c @@ -113,7 +113,7 @@ int pthread_cond_clockwait(FAR pthread_cond_t *cond, sinfo("Give up mutex...\n"); - atomic_fetch_add(COND_WAIT_COUNT(cond), 1); + atomic_add(COND_WAIT_COUNT(cond), 1); /* Give up the mutex */ diff --git a/libs/libc/pthread/pthread_condwait.c b/libs/libc/pthread/pthread_condwait.c index 0326e64b4e235..840daa36ff105 100644 --- a/libs/libc/pthread/pthread_condwait.c +++ b/libs/libc/pthread/pthread_condwait.c @@ -90,7 +90,7 @@ int pthread_cond_wait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex) sinfo("Give up mutex / take cond\n"); - atomic_fetch_add(COND_WAIT_COUNT(cond), 1); + atomic_add(COND_WAIT_COUNT(cond), 1); ret = pthread_mutex_breaklock(mutex, &nlocks); status = -nxsem_wait_uninterruptible(&cond->sem); diff --git a/sched/addrenv/addrenv.c b/sched/addrenv/addrenv.c index 32e6cba247c67..2d9b59a8a9e81 100644 --- a/sched/addrenv/addrenv.c +++ b/sched/addrenv/addrenv.c @@ -469,7 +469,7 @@ void addrenv_take(FAR struct addrenv_s *addrenv) if (addrenv != NULL) { - atomic_fetch_add(&addrenv->refs, 1); + atomic_add(&addrenv->refs, 1); } } @@ -495,7 +495,7 @@ int addrenv_give(FAR struct addrenv_s *addrenv) * address environment has become unreferenced and should be destroyed. */ - return addrenv ? atomic_fetch_sub(&addrenv->refs, 1) - 1 : 1; + return addrenv ? atomic_sub(&addrenv->refs, 1) - 1 : 1; } /**************************************************************************** diff --git a/sched/semaphore/sem_holder.c b/sched/semaphore/sem_holder.c index a124f7c3fa440..1df007a75db06 100644 --- a/sched/semaphore/sem_holder.c +++ b/sched/semaphore/sem_holder.c @@ -982,7 +982,7 @@ void nxsem_release_all(FAR struct tcb_s *htcb) * that was taken by sem_wait() or sem_post(). */ - atomic_fetch_add(NXSEM_COUNT(sem), 1); + atomic_add(NXSEM_COUNT(sem), 1); } } } diff --git a/sched/semaphore/sem_post.c b/sched/semaphore/sem_post.c index 8018a1d869a63..6f191ed5a0880 100644 --- a/sched/semaphore/sem_post.c +++ b/sched/semaphore/sem_post.c @@ -96,7 +96,7 @@ int nxsem_post_slow(FAR sem_t *sem) /* Lock the mutex for us by setting the blocking bit */ - mholder = atomic_fetch_or(NXSEM_MHOLDER(sem), NXSEM_MBLOCKING_BIT); + mholder = atomic_or(NXSEM_MHOLDER(sem), NXSEM_MBLOCKING_BIT); /* Mutex post from another thread is not allowed, unless * called from nxsem_reset. The comparison uses the same encoding diff --git a/sched/semaphore/sem_recover.c b/sched/semaphore/sem_recover.c index c823d6dbca6ce..59f86446b7b84 100644 --- a/sched/semaphore/sem_recover.c +++ b/sched/semaphore/sem_recover.c @@ -112,14 +112,14 @@ void nxsem_recover(FAR struct tcb_s *tcb) if (dq_empty(SEM_WAITLIST(sem))) { uint32_t mholder = - atomic_fetch_and(NXSEM_MHOLDER(sem), ~NXSEM_MBLOCKING_BIT); + atomic_and(NXSEM_MHOLDER(sem), ~NXSEM_MBLOCKING_BIT); DEBUGASSERT(NXSEM_MBLOCKING(mholder)); } } else { DEBUGASSERT(atomic_read(NXSEM_COUNT(sem)) < 0); - atomic_fetch_add(NXSEM_COUNT(sem), 1); + atomic_add(NXSEM_COUNT(sem), 1); } #ifdef CONFIG_MM_KMAP diff --git a/sched/semaphore/sem_trywait.c b/sched/semaphore/sem_trywait.c index 40f2e10275c85..710d0a6461ec8 100644 --- a/sched/semaphore/sem_trywait.c +++ b/sched/semaphore/sem_trywait.c @@ -117,7 +117,7 @@ int nxsem_trywait_slow(FAR sem_t *sem) } else { - atomic_fetch_add(NXSEM_COUNT(sem), 1); + atomic_add(NXSEM_COUNT(sem), 1); } } else diff --git a/sched/semaphore/sem_wait.c b/sched/semaphore/sem_wait.c index a8391b13b9ff5..7481b2fa7c911 100644 --- a/sched/semaphore/sem_wait.c +++ b/sched/semaphore/sem_wait.c @@ -117,7 +117,7 @@ int nxsem_wait_slow(FAR sem_t *sem) * this is all that is needed if we block */ - mholder = atomic_fetch_or(NXSEM_MHOLDER(sem), NXSEM_MBLOCKING_BIT); + mholder = atomic_or(NXSEM_MHOLDER(sem), NXSEM_MBLOCKING_BIT); /* Avoid mutex recursion, which is not allowed. The comparison uses * the lock side's encoding so that ids of either sign compare the @@ -143,7 +143,7 @@ int nxsem_wait_slow(FAR sem_t *sem) } else { - unlocked = atomic_fetch_sub(NXSEM_COUNT(sem), 1) > 0; + unlocked = atomic_sub(NXSEM_COUNT(sem), 1) > 0; } if (unlocked) @@ -160,7 +160,7 @@ int nxsem_wait_slow(FAR sem_t *sem) } else { - atomic_fetch_add(NXSEM_COUNT(sem), 1); + atomic_add(NXSEM_COUNT(sem), 1); } leave_critical_section(flags); diff --git a/sched/semaphore/sem_waitirq.c b/sched/semaphore/sem_waitirq.c index e0eec5e42e0cf..ae86b861e8810 100644 --- a/sched/semaphore/sem_waitirq.c +++ b/sched/semaphore/sem_waitirq.c @@ -105,12 +105,12 @@ void nxsem_wait_irq(FAR struct tcb_s *wtcb, int errcode) { if (dq_empty(SEM_WAITLIST(sem))) { - atomic_fetch_and(NXSEM_MHOLDER(sem), ~NXSEM_MBLOCKING_BIT); + atomic_and(NXSEM_MHOLDER(sem), ~NXSEM_MBLOCKING_BIT); } } else { - atomic_fetch_add(NXSEM_COUNT(sem), 1); + atomic_add(NXSEM_COUNT(sem), 1); } /* Indicate that the wait is over. */ diff --git a/wireless/bluetooth/bt_atomic.h b/wireless/bluetooth/bt_atomic.h index 6666bab7c7f62..9b2db202332a1 100644 --- a/wireless/bluetooth/bt_atomic.h +++ b/wireless/bluetooth/bt_atomic.h @@ -40,12 +40,12 @@ #define bt_atomic_set(ptr, value) atomic_set(ptr, value); #define bt_atomic_get(ptr) atomic_read(ptr) #define bt_atomic_testbit(ptr, bitno) ((atomic_read(ptr) & (1 << (bitno))) != 0) -#define bt_atomic_incr(ptr) atomic_fetch_add(ptr, 1) -#define bt_atomic_decr(ptr) atomic_fetch_sub(ptr, 1) -#define bt_atomic_setbit(ptr, bitno) atomic_fetch_or(ptr, (1 << (bitno))) -#define bt_atomic_clrbit(ptr, bitno) atomic_fetch_and(ptr, ~(1 << (bitno))) -#define bt_atomic_testsetbit(ptr, bitno) ((atomic_fetch_or(ptr, (1 << (bitno))) & (1 << (bitno))) != 0) -#define bt_atomic_testclrbit(ptr, bitno) ((atomic_fetch_and(ptr, ~(1 << (bitno))) & (1 << (bitno))) != 0) +#define bt_atomic_incr(ptr) atomic_add(ptr, 1) +#define bt_atomic_decr(ptr) atomic_sub(ptr, 1) +#define bt_atomic_setbit(ptr, bitno) atomic_or(ptr, (1 << (bitno))) +#define bt_atomic_clrbit(ptr, bitno) atomic_and(ptr, ~(1 << (bitno))) +#define bt_atomic_testsetbit(ptr, bitno) ((atomic_or(ptr, (1 << (bitno))) & (1 << (bitno))) != 0) +#define bt_atomic_testclrbit(ptr, bitno) ((atomic_and(ptr, ~(1 << (bitno))) & (1 << (bitno))) != 0) /**************************************************************************** * Public Types From 2aa1e74d31a566cf2c0994de3e3530daf8c9e5ca Mon Sep 17 00:00:00 2001 From: zhangyu117 Date: Wed, 12 Aug 2026 15:28:17 +0800 Subject: [PATCH 10/14] nuttx/atomic.h: use _Atomic define atomic_t. 1. use _atomic as wrapper because if _Atomic empty, may affects the compilation of other files: 2. for clang builtin function, it donot accept param with keyword "_Atomic" Signed-off-by: zhangyu117 --- include/nuttx/atomic.h | 5 ++-- include/nuttx/compiler.h | 65 ++++++++++++++++++---------------------- tools/nxstyle.c | 4 +++ 3 files changed, 35 insertions(+), 39 deletions(-) diff --git a/include/nuttx/atomic.h b/include/nuttx/atomic.h index 9f466ff7dd4f1..aa381a4402ee0 100644 --- a/include/nuttx/atomic.h +++ b/include/nuttx/atomic.h @@ -159,9 +159,8 @@ * Public Types ****************************************************************************/ -typedef volatile int32_t atomic_t; -typedef volatile int64_t atomic64_t; - +typedef __Atomic(int32_t) atomic_t; +typedef __Atomic(int64_t) atomic64_t; /**************************************************************************** * Public Function Prototypes diff --git a/include/nuttx/compiler.h b/include/nuttx/compiler.h index 32a2a96d765f3..00f926a351026 100644 --- a/include/nuttx/compiler.h +++ b/include/nuttx/compiler.h @@ -79,6 +79,15 @@ # define CONFIG_HAVE_CXX14 1 #endif +/* Keyword about _Atomic */ + +#if defined(__cplusplus) || defined(__clang__) || \ + !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L +# define __Atomic(t) t +#else +# define __Atomic(t) _Atomic(t) +#endif + /* Green Hills Software definitions *****************************************/ #if defined(__ghs__) @@ -1383,44 +1392,28 @@ /* 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_store_4(obj, val, memorder) __c11_atomic_store(obj, val, memorder) +# define atomic_store_8(obj, val, memorder) __c11_atomic_store(obj, val, memorder) +# define atomic_load_4(obj, memorder) __c11_atomic_load(obj, memorder) +# define atomic_load_8(obj, memorder) __c11_atomic_load(obj, memorder) +# define atomic_fetch_add_4(obj, val, memorder) __c11_atomic_add(obj, val, memorder) +# define atomic_fetch_add_8(obj, val, memorder) __c11_atomic_add(obj, val, memorder) +# define atomic_fetch_sub_4(obj, val, memorder) __c11_atomic_sub(obj, val, memorder) +# define atomic_fetch_sub_8(obj, val, memorder) __c11_atomic_sub(obj, val, memorder) +# define atomic_fetch_and_4(obj, val, memorder) __c11_atomic_and(obj, val, memorder) +# define atomic_fetch_and_8(obj, val, memorder) __c11_atomic_and(obj, val, memorder) +# define atomic_fetch_or_4(obj, val, memorder) __c11_atomic_or(obj, val, memorder) +# define atomic_fetch_or_8(obj, val, memorder) __c11_atomic_or(obj, val, memorder) +# define atomic_fetch_xor_4(obj, val, memorder) __c11_atomic_xor(obj, val, memorder) +# define atomic_fetch_xor_8(obj, val, memorder) __c11_atomic_xor(obj, val, memorder) +# define atomic_exchange_4(obj, val, memorder) __c11_atomic_exchange(obj, val, memorder) +# define atomic_exchange_8(obj, val, memorder) __c11_atomic_exchange(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)) + ((weak) ? __c11_atomic_compare_exchange_weak(obj, expected, desired, success, failure) \ + : __c11_atomic_compare_exchange_strong(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)) + ((weak) ? __c11_atomic_compare_exchange_weak(obj, expected, desired, success, failure) \ + : __c11_atomic_compare_exchange_strong(obj, expected, desired, success, failure)) # endif /* Unknown compiler *********************************************************/ diff --git a/tools/nxstyle.c b/tools/nxstyle.c index 89683934df7df..f590fef218f57 100644 --- a/tools/nxstyle.c +++ b/tools/nxstyle.c @@ -364,6 +364,10 @@ static const char *g_white_content_list[] = "_Atomic", + /* Ref: include/nuttx/atomic.h */ + + "__Atomic", + /* Ref: https://en.cppreference.com/w/c/keyword/_Thread_local */ "_Thread_local", From 9a699c75eb994066788054f86679350114f4baf4 Mon Sep 17 00:00:00 2001 From: zhangyu117 Date: Mon, 10 Nov 2025 12:18:46 +0800 Subject: [PATCH 11/14] nuttx/hwspinlock: hwspinlock should based on irq instead of spinlock_irq Use irq-based critical sections instead of spinlock_irq to avoid potential deadlock in atomic contexts. Signed-off-by: zhangyu117 --- include/nuttx/hwspinlock/hwspinlock.h | 50 ++++++++++++--------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/include/nuttx/hwspinlock/hwspinlock.h b/include/nuttx/hwspinlock/hwspinlock.h index deee7ff183fc4..00b4a5d7dc0c0 100644 --- a/include/nuttx/hwspinlock/hwspinlock.h +++ b/include/nuttx/hwspinlock/hwspinlock.h @@ -28,8 +28,7 @@ ****************************************************************************/ #include -#include - +#include #include /**************************************************************************** @@ -40,16 +39,15 @@ struct hwspinlock_dev_s; struct hwspinlock_ops_s { - CODE bool (*trylock)(FAR struct hwspinlock_dev_s *dev, - int id, int priority); - CODE void (*relax)(FAR struct hwspinlock_dev_s *dev, - int id, int priority); - CODE void (*unlock)(FAR struct hwspinlock_dev_s *dev, int id); + CODE bool (*trylock)(FAR struct hwspinlock_dev_s *dev); + CODE void (*relax)(FAR struct hwspinlock_dev_s *dev); + CODE void (*unlock)(FAR struct hwspinlock_dev_s *dev); }; struct hwspinlock_dev_s { - spinlock_t lock; + int id; + int priority; FAR const struct hwspinlock_ops_s *ops; }; @@ -65,57 +63,53 @@ extern "C" #define EXTERN extern #endif -static inline bool hwspin_trylock(FAR struct hwspinlock_dev_s *dev, - int id, int priority) +static inline bool hwspin_trylock(FAR struct hwspinlock_dev_s *dev) { - return dev->ops->trylock(dev, id, priority); + return dev->ops->trylock(dev); } static inline bool hwspin_trylock_irqsave(FAR struct hwspinlock_dev_s *dev, - int id, int priority, FAR irqstate_t *flags) { - *flags = spin_lock_irqsave(&dev->lock); - if (hwspin_trylock(dev, id, priority)) + *flags = up_irq_save(); + if (hwspin_trylock(dev)) { return true; } - spin_unlock_irqrestore(&dev->lock, *flags); + up_irq_restore(*flags); return false; } -static inline void hwspin_lock(FAR struct hwspinlock_dev_s *dev, - int id, int priority) +static inline void hwspin_lock(FAR struct hwspinlock_dev_s *dev) { - while (!dev->ops->trylock(dev, id, priority)) + while (!dev->ops->trylock(dev)) { if (dev->ops->relax) { - dev->ops->relax(dev, id, priority); + dev->ops->relax(dev); } } } static inline irqstate_t -hwspin_lock_irqsave(FAR struct hwspinlock_dev_s *dev, - int id, int priority) +hwspin_lock_irqsave(FAR struct hwspinlock_dev_s *dev) { - irqstate_t flags = spin_lock_irqsave(&dev->lock); - hwspin_lock(dev, id, priority); + irqstate_t flags = up_irq_save(); + hwspin_lock(dev); return flags; } -static inline void hwspin_unlock(FAR struct hwspinlock_dev_s *dev, int id) +static inline void hwspin_unlock(FAR struct hwspinlock_dev_s *dev) { - dev->ops->unlock(dev, id); + dev->ops->unlock(dev); } static inline void hwspin_unlock_restore(FAR struct hwspinlock_dev_s *dev, - int id, irqstate_t flags) + irqstate_t flags) { - hwspin_unlock(dev, id); - spin_unlock_irqrestore(&dev->lock, flags); + hwspin_unlock(dev); + up_irq_restore(flags); } #ifdef __cplusplus From 45e03699e7302ecec0370ec9f5ff6f654a11ed55 Mon Sep 17 00:00:00 2001 From: zhangyu117 Date: Fri, 21 Aug 2026 11:47:44 +0800 Subject: [PATCH 12/14] arch/arm/src: add hwspinlock driver for cxd56, rp2040 and lc823450 Add hardware spinlock driver implementations for cxd56, rp2040, and lc823450 chips. These drivers provide the hwspinlock_ops_s interface used by the atomic hwspinlock backend. Signed-off-by: zhangyu117 --- arch/arm/src/cxd56xx/CMakeLists.txt | 3 +- arch/arm/src/cxd56xx/Make.defs | 1 + arch/arm/src/cxd56xx/cxd56_hwspinlock.c | 63 +++++++++++++++++ arch/arm/src/lc823450/Make.defs | 1 + arch/arm/src/lc823450/lc823450_hwspinlock.c | 76 +++++++++++++++++++++ arch/arm/src/rp2040/Make.defs | 1 + arch/arm/src/rp2040/rp2040_hwspinlock.c | 59 ++++++++++++++++ 7 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 arch/arm/src/cxd56xx/cxd56_hwspinlock.c create mode 100644 arch/arm/src/lc823450/lc823450_hwspinlock.c create mode 100644 arch/arm/src/rp2040/rp2040_hwspinlock.c diff --git a/arch/arm/src/cxd56xx/CMakeLists.txt b/arch/arm/src/cxd56xx/CMakeLists.txt index bd06dc25591a2..f6745758f22f4 100644 --- a/arch/arm/src/cxd56xx/CMakeLists.txt +++ b/arch/arm/src/cxd56xx/CMakeLists.txt @@ -39,7 +39,8 @@ set(SRCS cxd56_icc.c cxd56_powermgr.c cxd56_farapi.c - cxd56_sysctl.c) + cxd56_sysctl.c + cxd56_hwspinlock.c) if(CONFIG_SMP) list(APPEND SRCS cxd56_cpuidlestack.c) diff --git a/arch/arm/src/cxd56xx/Make.defs b/arch/arm/src/cxd56xx/Make.defs index 11f45965c4ac5..0c14887131e1c 100644 --- a/arch/arm/src/cxd56xx/Make.defs +++ b/arch/arm/src/cxd56xx/Make.defs @@ -39,6 +39,7 @@ CHIP_CSRCS += cxd56_icc.c CHIP_CSRCS += cxd56_powermgr.c CHIP_CSRCS += cxd56_farapi.c CHIP_CSRCS += cxd56_sysctl.c +CHIP_CSRCS += cxd56_hwspinlock.c ifeq ($(CONFIG_SMP),y) CHIP_CSRCS += cxd56_cpuidlestack.c diff --git a/arch/arm/src/cxd56xx/cxd56_hwspinlock.c b/arch/arm/src/cxd56xx/cxd56_hwspinlock.c new file mode 100644 index 0000000000000..074ea25b896b9 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_hwspinlock.c @@ -0,0 +1,63 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_hwspinlock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "arm_internal.h" +#include "hardware/cxd56_sph.h" + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static bool cxd56_hwspinlock_trylock(struct hwspinlock_dev_s *dev); +static void cxd56_hwspinlock_unlock(struct hwspinlock_dev_s *dev); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct hwspinlock_ops_s g_cxd56_hwspinlock_ops = +{ + .trylock = cxd56_hwspinlock_trylock, + .unlock = cxd56_hwspinlock_unlock +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static bool cxd56_hwspinlock_trylock(struct hwspinlock_dev_s *dev) +{ + uint32_t sphlocked = ((up_cpu_index() + 2) << 16) | 0x1; + + putreg32(REQ_LOCK, CXD56_SPH_REQ(dev->id)); + + return getreg32(CXD56_SPH_STS(dev->id)) == sphlocked; +} + +static void cxd56_hwspinlock_unlock(struct hwspinlock_dev_s *dev) +{ + putreg32(REQ_UNLOCK, CXD56_SPH_REQ(dev->id)); +} diff --git a/arch/arm/src/lc823450/Make.defs b/arch/arm/src/lc823450/Make.defs index 14e6f6216b57b..d6a60696eef82 100644 --- a/arch/arm/src/lc823450/Make.defs +++ b/arch/arm/src/lc823450/Make.defs @@ -25,6 +25,7 @@ include armv7-m/Make.defs CHIP_CSRCS = lc823450_allocateheap2.c lc823450_start.c lc823450_irq.c lc823450_timer.c CHIP_CSRCS += lc823450_lowputc.c lc823450_serial.c lc823450_clockconfig.c CHIP_CSRCS += lc823450_syscontrol.c lc823450_gpio.c +CHIP_CSRCS += lc823450_hwspinlock.c # Configuration-dependent LC823450 files diff --git a/arch/arm/src/lc823450/lc823450_hwspinlock.c b/arch/arm/src/lc823450/lc823450_hwspinlock.c new file mode 100644 index 0000000000000..d114100b7d073 --- /dev/null +++ b/arch/arm/src/lc823450/lc823450_hwspinlock.c @@ -0,0 +1,76 @@ +/**************************************************************************** + * arch/arm/src/lc823450/lc823450_hwspinlock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "arm_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define LC823450_MUTEX_REG_BASE 0x40005000 + +#define LC823450_MUTEX_REG_LEN 4 +#define LC823450_MUTEX_REG_ADDR(id) \ + (LC823450_MUTEX_REG_BASE + (id) * LC823450_MUTEX_REG_LEN) + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static bool lc823450_hwspinlock_trylock(struct hwspinlock_dev_s *dev); +static void lc823450_hwspinlock_unlock(struct hwspinlock_dev_s *dev); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct hwspinlock_ops_s g_lc823450_hwspinlock_ops = +{ + .trylock = lc823450_hwspinlock_trylock, + .unlock = lc823450_hwspinlock_unlock +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static bool lc823450_hwspinlock_trylock(struct hwspinlock_dev_s *dev) +{ + uint32_t val; + + val = (up_cpu_index() << 16) | 0x1; + putreg32(val, LC823450_MUTEX_REG_ADDR(dev->id)); + + return getreg32(LC823450_MUTEX_REG_ADDR(dev->id)) == val; +} + +static void lc823450_hwspinlock_unlock(struct hwspinlock_dev_s *dev) +{ + uint32_t val; + + val = (up_cpu_index() << 16) | 0x0; + putreg32(val, LC823450_MUTEX_REG_ADDR(dev->id)); +} diff --git a/arch/arm/src/rp2040/Make.defs b/arch/arm/src/rp2040/Make.defs index 2eeabede0b946..43685810274c4 100644 --- a/arch/arm/src/rp2040/Make.defs +++ b/arch/arm/src/rp2040/Make.defs @@ -35,6 +35,7 @@ CHIP_CSRCS += rp2040_pio.c CHIP_CSRCS += rp2040_clock.c CHIP_CSRCS += rp2040_xosc.c CHIP_CSRCS += rp2040_pll.c +CHIP_CSRCS += rp2040_hwspinlock.c ifeq ($(CONFIG_SMP),y) CHIP_CSRCS += rp2040_cpustart.c diff --git a/arch/arm/src/rp2040/rp2040_hwspinlock.c b/arch/arm/src/rp2040/rp2040_hwspinlock.c new file mode 100644 index 0000000000000..9cc762f1e194d --- /dev/null +++ b/arch/arm/src/rp2040/rp2040_hwspinlock.c @@ -0,0 +1,59 @@ +/**************************************************************************** + * arch/arm/src/rp2040/rp2040_hwspinlock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "arm_internal.h" +#include "hardware/rp2040_sio.h" + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static bool rp2040_hwspinlock_trylock(struct hwspinlock_dev_s *dev); +static void rp2040_hwspinlock_unlock(struct hwspinlock_dev_s *dev); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct hwspinlock_ops_s g_rp2040_hwspinlock_ops = +{ + .trylock = rp2040_hwspinlock_trylock, + .unlock = rp2040_hwspinlock_unlock +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static bool rp2040_hwspinlock_trylock(struct hwspinlock_dev_s *dev) +{ + return getreg32(RP2040_SIO_SPINLOCK(dev->id)); +} + +static void rp2040_hwspinlock_unlock(struct hwspinlock_dev_s *dev) +{ + putreg32(0, RP2040_SIO_SPINLOCK(dev->id)); +} From cbb6a71a1b067c273b0e2a655286e14271e2f035 Mon Sep 17 00:00:00 2001 From: zhangyu117 Date: Wed, 19 Aug 2026 22:30:24 +0800 Subject: [PATCH 13/14] libc/machine: realize atomic based on hwspinlock Implement atomic_lock/atomic_unlock using hwspinlock when CONFIG_LIBC_ATOMIC_HWSPINLOCK is selected, and using up_irq_save/ up_irq_restore when CONFIG_LIBC_ATOMIC_IRQ is selected. Rename arch_atomic_irq.c to arch_atomic.c. The 64-bit atomic operations use spinlock (spin_lock_irqsave) regardless of the selected backend, ensuring multi-core safety. Signed-off-by: zhangyu117 --- libs/libc/machine/CMakeLists.txt | 4 ++-- libs/libc/machine/Make.defs | 4 ++-- .../{arch_atomic_irq.c => arch_atomic.c} | 19 ++++++++++++++++++- 3 files changed, 22 insertions(+), 5 deletions(-) rename libs/libc/machine/{arch_atomic_irq.c => arch_atomic.c} (97%) diff --git a/libs/libc/machine/CMakeLists.txt b/libs/libc/machine/CMakeLists.txt index 148039dec6c7a..35bbf1cbaffa9 100644 --- a/libs/libc/machine/CMakeLists.txt +++ b/libs/libc/machine/CMakeLists.txt @@ -22,8 +22,8 @@ add_subdirectory(${CONFIG_ARCH}) -if(CONFIG_LIBC_ATOMIC_IRQ) - target_sources(c PRIVATE arch_atomic_irq.c) +if(CONFIG_LIBC_ATOMIC_IRQ OR CONFIG_LIBC_ATOMIC_HWSPINLOCK) + target_sources(c PRIVATE arch_atomic.c) endif() target_sources(c PRIVATE arch_atomic64.c) diff --git a/libs/libc/machine/Make.defs b/libs/libc/machine/Make.defs index 5821f401ef737..e8e03b6543f10 100644 --- a/libs/libc/machine/Make.defs +++ b/libs/libc/machine/Make.defs @@ -20,8 +20,8 @@ # ############################################################################ -ifeq ($(CONFIG_LIBC_ATOMIC_IRQ),y) - CSRCS += arch_atomic_irq.c +ifneq ($(filter y,$(CONFIG_LIBC_ATOMIC_IRQ)$(CONFIG_LIBC_ATOMIC_HWSPINLOCK)),) + CSRCS += arch_atomic.c endif CSRCS += arch_atomic64.c diff --git a/libs/libc/machine/arch_atomic_irq.c b/libs/libc/machine/arch_atomic.c similarity index 97% rename from libs/libc/machine/arch_atomic_irq.c rename to libs/libc/machine/arch_atomic.c index 483d7b1fed385..802514c3bd403 100644 --- a/libs/libc/machine/arch_atomic_irq.c +++ b/libs/libc/machine/arch_atomic.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libs/libc/machine/arch_atomic_irq.c + * libs/libc/machine/arch_atomic.c * * SPDX-License-Identifier: Apache-2.0 * @@ -30,6 +30,9 @@ #include #include #include +#if defined(CONFIG_LIBC_ATOMIC_HWSPINLOCK) +# include +#endif #include "arch_atomic.h" @@ -37,6 +40,19 @@ * Private Functions ****************************************************************************/ +#if defined(CONFIG_LIBC_ATOMIC_HWSPINLOCK) +extern struct hwspinlock_dev_s g_atomic_hwspinlock; + +static inline irqstate_t atomic_lock(void) +{ + return hwspin_lock_irqsave(&g_atomic_hwspinlock); +} + +static inline void atomic_unlock(irqstate_t flags) +{ + hwspin_unlock_restore(&g_atomic_hwspinlock, flags); +} +#elif defined(CONFIG_LIBC_ATOMIC_IRQ) static inline irqstate_t atomic_lock(void) { return up_irq_save(); @@ -46,6 +62,7 @@ static inline void atomic_unlock(irqstate_t flags) { up_irq_restore(flags); } +#endif /**************************************************************************** * Public Functions From afb4c2c134037f9e28a8e8aa8d2cbc3a4177be2b Mon Sep 17 00:00:00 2001 From: zhangyu117 Date: Fri, 14 Aug 2026 14:58:38 +0800 Subject: [PATCH 14/14] arch/arm/src: realize atomic for cxd56, rp2040 and lc823450 Add per-chip atomic hwspinlock device definitions for cxd56, rp2040, and lc823450. These provide the hardware spinlock device used by the atomic hwspinlock backend for multi-core atomic operations. Replace CXD56_TESTSET/CXD56_TESTSET_WITH_HWSEM with CXD56_ATOMIC_WITH_HWSEM which selects LIBC_ATOMIC_HWSPINLOCK, bridging the old chip-specific testset mechanism to the new generic atomic backend framework. Signed-off-by: zhangyu117 --- arch/arm/src/cxd56xx/CMakeLists.txt | 3 +- arch/arm/src/cxd56xx/Kconfig | 6 +++ arch/arm/src/cxd56xx/Make.defs | 1 + arch/arm/src/cxd56xx/cxd56_atomic.c | 50 +++++++++++++++++++++++++ arch/arm/src/cxd56xx/cxd56_sph.c | 6 ++- arch/arm/src/lc823450/Make.defs | 1 + arch/arm/src/lc823450/lc823450_atomic.c | 50 +++++++++++++++++++++++++ arch/arm/src/rp2040/Make.defs | 1 + arch/arm/src/rp2040/rp2040_atomic.c | 50 +++++++++++++++++++++++++ 9 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 arch/arm/src/cxd56xx/cxd56_atomic.c create mode 100644 arch/arm/src/lc823450/lc823450_atomic.c create mode 100644 arch/arm/src/rp2040/rp2040_atomic.c diff --git a/arch/arm/src/cxd56xx/CMakeLists.txt b/arch/arm/src/cxd56xx/CMakeLists.txt index f6745758f22f4..f7bdb5aa9b7fb 100644 --- a/arch/arm/src/cxd56xx/CMakeLists.txt +++ b/arch/arm/src/cxd56xx/CMakeLists.txt @@ -40,7 +40,8 @@ set(SRCS cxd56_powermgr.c cxd56_farapi.c cxd56_sysctl.c - cxd56_hwspinlock.c) + cxd56_hwspinlock.c + cxd56_atomic.c) if(CONFIG_SMP) list(APPEND SRCS cxd56_cpuidlestack.c) diff --git a/arch/arm/src/cxd56xx/Kconfig b/arch/arm/src/cxd56xx/Kconfig index 5b2f5af3de38d..f1cc8634117f1 100644 --- a/arch/arm/src/cxd56xx/Kconfig +++ b/arch/arm/src/cxd56xx/Kconfig @@ -1429,6 +1429,12 @@ config CXD56_TESTSET_WITH_HWSEM endif # CXD56_TESTSET +config CXD56_ATOMIC_WITH_HWSEM + bool "Use atomic based on hardware semaphore" + default !CXD56_USE_SYSBUS + depends on SMP + select LIBC_ATOMIC_HWSPINLOCK + config CXD56_USE_SYSBUS bool "Use the system bus for the data section" default y diff --git a/arch/arm/src/cxd56xx/Make.defs b/arch/arm/src/cxd56xx/Make.defs index 0c14887131e1c..04e9ee59d0155 100644 --- a/arch/arm/src/cxd56xx/Make.defs +++ b/arch/arm/src/cxd56xx/Make.defs @@ -39,6 +39,7 @@ CHIP_CSRCS += cxd56_icc.c CHIP_CSRCS += cxd56_powermgr.c CHIP_CSRCS += cxd56_farapi.c CHIP_CSRCS += cxd56_sysctl.c +CHIP_CSRCS += cxd56_atomic.c CHIP_CSRCS += cxd56_hwspinlock.c ifeq ($(CONFIG_SMP),y) diff --git a/arch/arm/src/cxd56xx/cxd56_atomic.c b/arch/arm/src/cxd56xx/cxd56_atomic.c new file mode 100644 index 0000000000000..2736b3fd9de7d --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_atomic.c @@ -0,0 +1,50 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_atomic.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SPH_SMP 13 + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern const struct hwspinlock_ops_s g_cxd56_hwspinlock_ops; + +struct hwspinlock_dev_s g_atomic_hwspinlock = +{ + .id = SPH_SMP, + .priority = 0, + .ops = &g_cxd56_hwspinlock_ops +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/cxd56xx/cxd56_sph.c b/arch/arm/src/cxd56xx/cxd56_sph.c index 5f9d68e33cb7d..3b3f9bb0acf48 100644 --- a/arch/arm/src/cxd56xx/cxd56_sph.c +++ b/arch/arm/src/cxd56xx/cxd56_sph.c @@ -270,9 +270,11 @@ int cxd56_sphinitialize(const char *devname) int ret; int i; - /* No. 0-2 and (14)-15 semaphores are reserved by other system. */ + /* No. 0-2 and (13)-15 semaphores are reserved by other system. */ -#ifdef CONFIG_CXD56_TESTSET +#if defined(CONFIG_CXD56_ATOMIC_WITH_HWSEM) + for (i = 3; i < 13; i++) +#elif defined(CONFIG_CXD56_TESTSET_WITH_HWSEM) for (i = 3; i < 14; i++) #else for (i = 3; i < 15; i++) diff --git a/arch/arm/src/lc823450/Make.defs b/arch/arm/src/lc823450/Make.defs index d6a60696eef82..acff774bee0f9 100644 --- a/arch/arm/src/lc823450/Make.defs +++ b/arch/arm/src/lc823450/Make.defs @@ -124,3 +124,4 @@ endif ifeq ($(CONFIG_ARM_MPU),y) CHIP_CSRCS += lc823450_mpuinit2.c endif +CHIP_CSRCS += lc823450_atomic.c diff --git a/arch/arm/src/lc823450/lc823450_atomic.c b/arch/arm/src/lc823450/lc823450_atomic.c new file mode 100644 index 0000000000000..14428595272e5 --- /dev/null +++ b/arch/arm/src/lc823450/lc823450_atomic.c @@ -0,0 +1,50 @@ +/**************************************************************************** + * arch/arm/src/lc823450/lc823450_atomic.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define LC823450_MUTEX_REG 0 + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern const struct hwspinlock_ops_s g_lc823450_hwspinlock_ops; + +struct hwspinlock_dev_s g_atomic_hwspinlock = +{ + .id = LC823450_MUTEX_REG, + .priority = 0, + .ops = &g_lc823450_hwspinlock_ops +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/rp2040/Make.defs b/arch/arm/src/rp2040/Make.defs index 43685810274c4..f617f2d6d0de9 100644 --- a/arch/arm/src/rp2040/Make.defs +++ b/arch/arm/src/rp2040/Make.defs @@ -104,3 +104,4 @@ ifneq ($(PICO_SDK_PATH),) include chip/boot2/Make.defs endif endif +CHIP_CSRCS += rp2040_atomic.c diff --git a/arch/arm/src/rp2040/rp2040_atomic.c b/arch/arm/src/rp2040/rp2040_atomic.c new file mode 100644 index 0000000000000..b1c3f9bf0ff78 --- /dev/null +++ b/arch/arm/src/rp2040/rp2040_atomic.c @@ -0,0 +1,50 @@ +/**************************************************************************** + * arch/arm/src/rp2040/rp2040_atomic.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define RP2040_HWSPINLOCK 0 + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern const struct hwspinlock_ops_s g_rp2040_hwspinlock_ops; + +struct hwspinlock_dev_s g_atomic_hwspinlock = +{ + .id = RP2040_HWSPINLOCK, + .priority = 0, + .ops = &g_rp2040_hwspinlock_ops +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/