From de4f23748212dbba7d0250fdac3ae583e74fcbed Mon Sep 17 00:00:00 2001 From: Yaochenger <75192526+Yaochenger@users.noreply.github.com> Date: Thu, 23 Mar 2023 20:06:50 +0800 Subject: [atomic]添加arm与risc-v下的常用原子操作函数 (#7053) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update Kconfig * Update trap_gcc.S * Update bsp/hifive1/drivers/SConscript Co-authored-by: Man, Jianting (Meco) <920369182@qq.com> * Update SConscript * [atomic]提交一份arm与risc-v架构下的常用原子操作函数 * 修改变量类型 * 更新rtatomic.h与atomic_port.c * 更新rt-thread\libcpu\arm\common\atomic_port.c * 更新include/rtatomic.h与libcpu/arm/common/SConscript * 更新include/rtatomic.h * 修正格式与Kconfig * 修正格式与文件结构 * 规范文件格式与文件重命名 * 添加测试用例与CI * 添加函数声明 * 修改virt64/SConscript 添加atomic_riscv.c * 1.规范代码风格 * 2.添加RISC-V64原子指令支持 解决在RV64下编译器将32-bit运算结果扩展为64-bit 导致判断错误 * 添加C11标准库原子操作测试 --------- Co-authored-by: Man, Jianting (Meco) <920369182@qq.com> --- examples/utest/configs/kernel/atomic.conf | 4 + examples/utest/configs/kernel/atomic_c11.conf | 5 + examples/utest/testcases/kernel/Kconfig | 4 + examples/utest/testcases/kernel/SConscript | 3 + examples/utest/testcases/kernel/atomic_tc.c | 147 ++++++++++++++++++++++++++ 5 files changed, 163 insertions(+) create mode 100644 examples/utest/configs/kernel/atomic.conf create mode 100644 examples/utest/configs/kernel/atomic_c11.conf create mode 100644 examples/utest/testcases/kernel/atomic_tc.c (limited to 'examples') diff --git a/examples/utest/configs/kernel/atomic.conf b/examples/utest/configs/kernel/atomic.conf new file mode 100644 index 0000000000..4255cc2d4f --- /dev/null +++ b/examples/utest/configs/kernel/atomic.conf @@ -0,0 +1,4 @@ +CONFIG_UTEST_ATOMIC_TC=y +# dependencies +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_USING_THREAD=y diff --git a/examples/utest/configs/kernel/atomic_c11.conf b/examples/utest/configs/kernel/atomic_c11.conf new file mode 100644 index 0000000000..d98963f491 --- /dev/null +++ b/examples/utest/configs/kernel/atomic_c11.conf @@ -0,0 +1,5 @@ +CONFIG_UTEST_ATOMIC_TC=y +# dependencies +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_USING_THREAD=y +CONFIG_RT_USING_STDC_ATOMIC=y diff --git a/examples/utest/testcases/kernel/Kconfig b/examples/utest/testcases/kernel/Kconfig index 0faa3622fb..543baf6fa7 100644 --- a/examples/utest/testcases/kernel/Kconfig +++ b/examples/utest/testcases/kernel/Kconfig @@ -55,4 +55,8 @@ config UTEST_THREAD_TC select RT_USING_TIMER_SOFT select RT_USING_THREAD +config UTEST_ATOMIC_TC + bool "atomic test" + default n + endmenu diff --git a/examples/utest/testcases/kernel/SConscript b/examples/utest/testcases/kernel/SConscript index 1cedc291c4..5d560e076b 100644 --- a/examples/utest/testcases/kernel/SConscript +++ b/examples/utest/testcases/kernel/SConscript @@ -41,6 +41,9 @@ if GetDepend(['UTEST_MAILBOX_TC']): if GetDepend(['UTEST_THREAD_TC']): src += ['thread_tc.c'] +if GetDepend(['UTEST_ATOMIC_TC']): + src += ['atomic_tc.c'] + group = DefineGroup('utestcases', src, depend = ['RT_USING_UTESTCASES'], CPPPATH = CPPPATH) Return('group') diff --git a/examples/utest/testcases/kernel/atomic_tc.c b/examples/utest/testcases/kernel/atomic_tc.c new file mode 100644 index 0000000000..53b1839e4f --- /dev/null +++ b/examples/utest/testcases/kernel/atomic_tc.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-07-27 flybreak the first version + * 2023-03-21 WangShun add atomic test + */ + +#include +#include "utest.h" +#include "rtatomic.h" +#include + +#define THREAD_PRIORITY 25 +#define THREAD_TIMESLICE 1 +#define THREAD_STACKSIZE 1024 + +/* convenience macro - return either 64-bit or 32-bit value */ +#define ATOMIC_WORD(val_if_64, val_if_32) \ + ((rt_atomic_t)((sizeof(void *) == sizeof(uint64_t)) ? (val_if_64) : (val_if_32))) + +static rt_atomic_t count = 0; +static rt_sem_t sem_t; + +static void test_atomic_api(void) +{ + rt_atomic_t base; + rt_atomic_t oldval; + + /* rt_atomic_t */ + uassert_true(sizeof(rt_atomic_t) == ATOMIC_WORD(sizeof(uint64_t), sizeof(uint32_t))); + + /* rt_atomic_add */ + base = 0; + rt_atomic_add(&base, 10); + uassert_true(base == 10); + /* rt_atomic_add negative */ + base = 2; + rt_atomic_add(&base, -4); + uassert_true(base == -2); + + /* rt_atomic_sub */ + base = 11; + rt_atomic_sub(&base, 10); + uassert_true(base == 1); + /* rt_atomic_sub negative */ + base = 2; + rt_atomic_sub(&base, -5); + uassert_true(base == 7); + + /* rt_atomic_or */ + base = 0xFF00; + rt_atomic_or(&base, 0x0F0F); + uassert_true(base == 0xFF0F); + + /* rt_atomic_xor */ + base = 0xFF00; + rt_atomic_xor(&base, 0x0F0F); + uassert_true(base == 0xF00F); + + /* rt_atomic_and */ + base = 0xFF00; + rt_atomic_and(&base, 0x0F0F); + uassert_true(base == 0x0F00); + + /* rt_atomic_exchange */ + base = 0xFF00; + rt_atomic_exchange(&base, 0x0F0F); + uassert_true(base == 0x0F0F); + + /* rt_atomic_flag_test_and_set */ + base = 0x0; + rt_atomic_flag_test_and_set(&base); + uassert_true(base == 0x1); + + /* rt_atomic_flag_clear */ + base = 0x1; + rt_atomic_flag_clear(&base); + uassert_true(base == 0x0); + + /* rt_atomic_load */ + base = 0xFF00; + rt_atomic_load(&base); + uassert_true(base == 0xFF00); + + /* rt_atomic_store */ + base = 0xFF00; + rt_atomic_store(&base, 0x0F0F); + uassert_true(base == 0x0F0F); + + /* rt_atomic_compare_exchange_strong */ + base = 10; + oldval = 10; + uassert_true(rt_atomic_compare_exchange_strong(&base, &oldval, 11) == 1); + uassert_true(base == 11); +} + +static void ture_entry(void *parameter) +{ + int i; + for(i = 0; i < 1000000; i++) + { + rt_atomic_add(&count, 1); + } + rt_sem_release(sem_t); +} + +static void test_atomic_add(void) +{ + rt_thread_t thread; + int i; + sem_t = rt_sem_create("atomic_sem", 0, RT_IPC_FLAG_PRIO); + + count = 0; + thread = rt_thread_create("t1", ture_entry, RT_NULL, THREAD_STACKSIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + rt_thread_startup(thread); + thread = rt_thread_create("t2", ture_entry, RT_NULL, THREAD_STACKSIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + rt_thread_startup(thread); + thread = rt_thread_create("t3", ture_entry, RT_NULL, THREAD_STACKSIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + rt_thread_startup(thread); + + for(i = 0; i < 3; i++) + { + rt_sem_take(sem_t, RT_WAITING_FOREVER); + } + uassert_true(count == 3000000); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(test_atomic_api); + UTEST_UNIT_RUN(test_atomic_add); +} +UTEST_TC_EXPORT(testcase, "testcases.kernel.atomic_tc", utest_tc_init, utest_tc_cleanup, 10); -- cgit v1.3.1