fix(newlib): add missing __atomic_test_and_set for RISCV chips wo 'a' extension

Before the change described in
https://gcc.gnu.org/pipermail/gcc-patches/2023-September/631393.html it
appeared that inlining built-in GCC function __atomic_test_and_set() was
incorrect. It resulted in a non-atomic write.
After the change now present in GCC, the IDF should include the function
__atomic_test_and_set() to successfully link the final binary.

Closes https://github.com/espressif/esp-idf/issues/15167
This commit is contained in:
Alexey Lapshin 2025-01-13 12:49:52 +07:00
parent 90fbd41701
commit 793e394f5a
2 changed files with 24 additions and 3 deletions

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -32,6 +32,14 @@ ATOMIC_FUNCTIONS(1, unsigned char)
ATOMIC_FUNCTIONS(2, short unsigned int)
ATOMIC_FUNCTIONS(4, unsigned int)
#ifndef __clang__
/* LLVM automatically replaces __atomic_test_and_set -> __atomic_exchange_1 call when compiling */
bool __atomic_test_and_set(volatile void *ptr, int memorder)
{
return __atomic_exchange_1(ptr, true, memorder);
}
#endif
#elif __riscv_atomic == 1
bool CLANG_ATOMIC_SUFFIX(__atomic_always_lock_free)(unsigned int size, const volatile void *)

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -26,6 +26,19 @@ atomic_uint *g_atomic32;
atomic_ushort *g_atomic16;
atomic_uchar *g_atomic8;
TEST_CASE("stdatomic - test_atomic_flag", "[newlib_stdatomic]")
{
bool x8 = 0;
g_atomic8 = heap_caps_calloc(sizeof(*g_atomic8), 1, MALLOC_CAP_DEFAULT);
x8 = atomic_flag_test_and_set(g_atomic8);
TEST_ASSERT_EQUAL_HEX8(0x00, x8);
TEST_ASSERT_EQUAL_HEX8(0x01, *g_atomic8);
atomic_flag_clear(g_atomic8);
TEST_ASSERT_EQUAL_HEX8(0x00, *g_atomic8);
free(g_atomic8);
}
TEST_CASE("stdatomic - test_64bit_atomics", "[newlib_stdatomic]")
{
unsigned long long x64 = 0;
@ -262,7 +275,7 @@ TEST_CASE("stdatomic - test_" #NAME, "[newlib_stdatomic]")
free(var_##NAME); \
}
// Note that the assert at the end is doing an excat bitwise comparison.
// Note that the assert at the end is doing an exact bitwise comparison.
// This easily can fail due to rounding errors. However, there is currently
// no corresponding Unity assert macro for long double. USE THIS WITH CARE!
#define TEST_RACE_OPERATION_LONG_DOUBLE(NAME, LHSTYPE, PRE, POST, INIT, FINAL) \