From 806fcddaf060976a1cf819f8f41dd14a30403fc1 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Tue, 22 Apr 2025 16:14:10 +0800 Subject: [PATCH 01/21] testing/drivertest: Fix timing issues on QEMU and sims. Since sim and qemu are not cycle accurate simulators, if the vCPU thread is preempted by other high priority tasks, it may cause timing issues. This is easy to happen when the test machine is busy. This commit modifies the condition of timing error and prints out the latency as a warning. Signed-off-by: ouyangxiangzhen --- testing/drivers/drivertest/drivertest_posix_timer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/testing/drivers/drivertest/drivertest_posix_timer.c b/testing/drivers/drivertest/drivertest_posix_timer.c index 00b7fb20317..d2855dfb445 100644 --- a/testing/drivers/drivertest/drivertest_posix_timer.c +++ b/testing/drivers/drivertest/drivertest_posix_timer.c @@ -41,7 +41,7 @@ * Pre-processor Definitions ****************************************************************************/ -#define RTC_DEFAULT_DEVIATION 10 +#define RTC_DEFAULT_DEVIATION 100 #define DEFAULT_TIME_OUT 2 #define SLEEPSECONDS 10 @@ -159,6 +159,8 @@ static void posix_timer_callback(union sigval arg) (FAR struct posix_timer_state_s *)arg.sival_ptr; int range = get_timestamp() - (*sigev_para).tim; + syslog(0, "range: %d ms\n", range); + assert_in_range(range, sigev_para->it.it_interval.tv_sec * 1000 - sigev_para->deviation, sigev_para->it.it_interval.tv_sec * 1000 + sigev_para->deviation); From a550f9760488b76d20e9ef7e289b494cfb1800f0 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 10 Jul 2025 11:05:42 +0800 Subject: [PATCH 02/21] testing/drivers: Fix posix timer assertions. On QEMU, if vcpus are preempted by other threads, the deviation of the timer might be very large, causing assertion failure. This commit addressed the problem. Signed-off-by: ouyangxiangzhen --- testing/drivers/drivertest/drivertest_posix_timer.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/testing/drivers/drivertest/drivertest_posix_timer.c b/testing/drivers/drivertest/drivertest_posix_timer.c index d2855dfb445..0870484cf49 100644 --- a/testing/drivers/drivertest/drivertest_posix_timer.c +++ b/testing/drivers/drivertest/drivertest_posix_timer.c @@ -161,9 +161,7 @@ static void posix_timer_callback(union sigval arg) syslog(0, "range: %d ms\n", range); - assert_in_range(range, - sigev_para->it.it_interval.tv_sec * 1000 - sigev_para->deviation, - sigev_para->it.it_interval.tv_sec * 1000 + sigev_para->deviation); + assert(range >= sigev_para->it.it_interval.tv_sec * 1000); syslog(LOG_DEBUG, "callback trigger!!!\n"); (*sigev_para).tim = get_timestamp(); From 1f98eff83397273c886eaf1279e2b79968f7aaf7 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 24 Jul 2025 20:31:32 +0800 Subject: [PATCH 03/21] testing/time: Relax the timing constraints. On SIM and QEMU, it is inevitable that the simulating vCPU got preempted by other threads, causing large timing delay. This commit relax the timing constraints to reduce the CT error. Signed-off-by: ouyangxiangzhen --- testing/testsuites/kernel/time/cases/clock_test_timer03.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/testsuites/kernel/time/cases/clock_test_timer03.c b/testing/testsuites/kernel/time/cases/clock_test_timer03.c index 7539f4479f6..76a42c76032 100644 --- a/testing/testsuites/kernel/time/cases/clock_test_timer03.c +++ b/testing/testsuites/kernel/time/cases/clock_test_timer03.c @@ -123,7 +123,7 @@ void test_nuttx_clock_test_timer03(FAR void **state) start.tv_sec * (int64_t)(1e9) - start.tv_nsec; failed += (escaped < expected || - (escaped - expected) >= 20000000); /* 20000000, 2 ticks. */ + (escaped - expected) > 100000000ul); /* 100 ms */ syslog(LOG_INFO, "expected = %" PRId64 " escaped = %" PRId64 "failed = %d", expected, escaped, failed); } From f060f2dbc2bed1512f14b7c8e0e6ab3d1539c77c Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 10 Jul 2025 11:05:42 +0800 Subject: [PATCH 04/21] testing/drivers: Fix posix timer assertions. On QEMU, if vcpus are preempted by other threads, the deviation of the timer might be very large, causing assertion failure. This commit addressed the problem. Signed-off-by: ouyangxiangzhen --- testing/drivers/drivertest/drivertest_posix_timer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testing/drivers/drivertest/drivertest_posix_timer.c b/testing/drivers/drivertest/drivertest_posix_timer.c index 0870484cf49..a9db327b896 100644 --- a/testing/drivers/drivertest/drivertest_posix_timer.c +++ b/testing/drivers/drivertest/drivertest_posix_timer.c @@ -161,7 +161,8 @@ static void posix_timer_callback(union sigval arg) syslog(0, "range: %d ms\n", range); - assert(range >= sigev_para->it.it_interval.tv_sec * 1000); + assert(range >= sigev_para->it.it_interval.tv_sec * 1000 - + sigev_para->deviation); syslog(LOG_DEBUG, "callback trigger!!!\n"); (*sigev_para).tim = get_timestamp(); From 3f9c0b893e27ff375ad503e1c10371f3a6a9d231 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Mon, 28 Jul 2025 14:12:18 +0800 Subject: [PATCH 05/21] testing/drivers: Fixed the wrong test-case. This commit fixed the wrong-test case where the time is acquired after the timer being set, leading to the assertion failure. Signed-off-by: ouyangxiangzhen --- testing/drivers/drivertest/drivertest_posix_timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/drivers/drivertest/drivertest_posix_timer.c b/testing/drivers/drivertest/drivertest_posix_timer.c index a9db327b896..469ecc198b2 100644 --- a/testing/drivers/drivertest/drivertest_posix_timer.c +++ b/testing/drivers/drivertest/drivertest_posix_timer.c @@ -196,11 +196,11 @@ static void drivertest_posix_timer(FAR void **state) /* Start the timer */ + posix_timer_state->tim = get_timestamp(); + ret = timer_settime(timerid, 0, &(posix_timer_state->it), NULL); assert_return_code(ret, OK); - posix_timer_state->tim = get_timestamp(); - /* Get the timer status */ ret = timer_gettime(timerid, &it); From 3c786cbed4faaac88f282a886c5074c39843bc61 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Tue, 31 Dec 2024 09:45:44 +0800 Subject: [PATCH 06/21] apps/testing: Fix Coverity. This commit is to make Coverity happy. Signed-off-by: ouyangxiangzhen --- testing/sched/timerjitter/timerjitter.c | 29 +++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/testing/sched/timerjitter/timerjitter.c b/testing/sched/timerjitter/timerjitter.c index 214bbf7356a..3a73ee29837 100644 --- a/testing/sched/timerjitter/timerjitter.c +++ b/testing/sched/timerjitter/timerjitter.c @@ -137,12 +137,15 @@ static FAR void *timerjitter(FAR void *arg) struct timespec next; struct timespec intv; struct itimerspec tspec; - struct sigevent sigev; sigset_t sigset; timer_t timer; int64_t diff; int sigs; int ret; + struct sigevent sigev = + { + 0 + }; sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); @@ -154,8 +157,20 @@ static FAR void *timerjitter(FAR void *arg) sigev.sigev_notify = SIGEV_SIGNAL; sigev.sigev_signo = SIGALRM; - timer_create(param->clockid, &sigev, &timer); - clock_gettime(param->clockid, &now); + ret = timer_create(param->clockid, &sigev, &timer); + + if (ret != 0) + { + printf("timer_create failed %d\n", ret); + return NULL; + } + + ret = clock_gettime(param->clockid, &now); + + if (ret) + { + printf("clock_gettime failed %d\n", ret); + } next = now; calc_next(&next, &intv); @@ -167,7 +182,13 @@ static FAR void *timerjitter(FAR void *arg) /* Using TIMER_ABSTIME */ tspec.it_value = next; - timer_settime(timer, TIMER_ABSTIME, &tspec, NULL); + ret = timer_settime(timer, TIMER_ABSTIME, &tspec, NULL); + + if (ret) + { + printf("timer_settime failed %d\n", ret); + return NULL; + } param->avg = 0; param->max = 0; From ce9aac97acc5aa6a307603f3de651e69c631a5da Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Fri, 21 Feb 2025 10:57:37 +0800 Subject: [PATCH 07/21] apps/testing: Fix timerjitter interval This commit increased the default interval of the timerjitter to avoid errors with large USEC_PER_TICK setting. Signed-off-by: ouyangxiangzhen --- testing/sched/timerjitter/timerjitter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/sched/timerjitter/timerjitter.c b/testing/sched/timerjitter/timerjitter.c index 3a73ee29837..56697b2bc77 100644 --- a/testing/sched/timerjitter/timerjitter.c +++ b/testing/sched/timerjitter/timerjitter.c @@ -35,7 +35,7 @@ ****************************************************************************/ #define DEFAULT_CLOCKID CLOCK_REALTIME -#define DEFAULT_INTERVAL 1000 +#define DEFAULT_INTERVAL 1000 * USEC_PER_TICK #define DEFAULT_ITERATION 1000 /* Fix compilation error for Non-NuttX OS */ From 91ed30aec05536e54f993bf062eb6ca5142f728b Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Mon, 24 Feb 2025 09:51:38 +0800 Subject: [PATCH 08/21] apps/testing: Fix timerjitter iteration This commit used the interval to calculate the timejitter iteration. Signed-off-by: ouyangxiangzhen --- testing/sched/timerjitter/timerjitter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/sched/timerjitter/timerjitter.c b/testing/sched/timerjitter/timerjitter.c index 56697b2bc77..01eed10d5b7 100644 --- a/testing/sched/timerjitter/timerjitter.c +++ b/testing/sched/timerjitter/timerjitter.c @@ -35,8 +35,8 @@ ****************************************************************************/ #define DEFAULT_CLOCKID CLOCK_REALTIME -#define DEFAULT_INTERVAL 1000 * USEC_PER_TICK -#define DEFAULT_ITERATION 1000 +#define DEFAULT_INTERVAL (1000 * USEC_PER_TICK) +#define DEFAULT_ITERATION (USEC_PER_SEC / DEFAULT_INTERVAL) /* Fix compilation error for Non-NuttX OS */ #ifndef FAR From 424d96bd0fabf88716e742c890d203099f5dd20d Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 3 Apr 2025 14:13:40 +0800 Subject: [PATCH 09/21] benchmark/taclebench: Add clock measurement. This commit added clock measurement for taclebench. Signed-off-by: ouyangxiangzhen --- ...dd-makefile-and-all-in-one-main-file.patch | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/benchmarks/tacle-bench/0001-tacle-bench-add-makefile-and-all-in-one-main-file.patch b/benchmarks/tacle-bench/0001-tacle-bench-add-makefile-and-all-in-one-main-file.patch index 4958ac5a8a5..fb1e2e400b9 100644 --- a/benchmarks/tacle-bench/0001-tacle-bench-add-makefile-and-all-in-one-main-file.patch +++ b/benchmarks/tacle-bench/0001-tacle-bench-add-makefile-and-all-in-one-main-file.patch @@ -1,10 +1,11 @@ -From 71f51cd5ca4f492a464fb12d5bce91e5fbba300a Mon Sep 17 00:00:00 2001 +From 6d0be04a4b4208447e75c369e9811d089f466739 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen -Date: Tue, 11 Jun 2024 16:01:23 +0800 +Date: Thu, 3 Apr 2025 11:59:02 +0800 Subject: [PATCH] tacle-bench: add makefile and all-in-one main file The original taclebench is used for WCET analysis. This commit allows most taclebench test cases (except parallel test cases) to be compiled and executed. +Change-Id: I707b8ac58d3ddc4b7974c5bedecac1a7b5c887f9 Signed-off-by: ouyangxiangzhen --- Makefile | 12 + @@ -65,14 +66,14 @@ Signed-off-by: ouyangxiangzhen bench/test/cover/cover.c | 3 + bench/test/duff/duff.c | 3 + bench/test/test3/test3.c | 3 + - taclebench.c | 349 ++++++++++++++++++ - 59 files changed, 532 insertions(+) + taclebench.c | 366 ++++++++++++++++++ + 59 files changed, 549 insertions(+) create mode 100644 Makefile create mode 100644 taclebench.c diff --git a/Makefile b/Makefile new file mode 100644 -index 0000000..2385c61 +index 0000000..75ca0a1 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ @@ -83,7 +84,7 @@ index 0000000..2385c61 +TEST_SRCS := $(shell find bench/test -name "*.c") + +all: -+ cc -DALL_IN_ONE ${APP_SRCS} ${KERNEL_SRCS} ${SEQUENTIAL_SRCS} ${TEST_SRCS} bench/kernel/cosf/wcclibm.c taclebench.c -static -o taclebench ++ cc -DALL_IN_ONE ${APP_SRCS} ${KERNEL_SRCS} ${SEQUENTIAL_SRCS} ${TEST_SRCS} bench/kernel/cosf/wcclibm.c taclebench.c -static -o taclebench -O3 + +clean: + rm -f taclebench @@ -888,11 +889,12 @@ index 0235738..6eaf8c2 100755 diff --git a/taclebench.c b/taclebench.c new file mode 100644 -index 0000000..1231b87 +index 0000000..aaff1bb --- /dev/null +++ b/taclebench.c -@@ -0,0 +1,349 @@ +@@ -0,0 +1,366 @@ +#include ++#include + +int main_epic(void); +int main_mpeg2(void); @@ -954,6 +956,10 @@ index 0000000..1231b87 + +int main(void) +{ ++ struct timespec start_ts; ++ struct timespec end_ts; ++ clock_gettime(CLOCK_MONOTONIC, &start_ts); ++ + if (main_epic() != 0) + { + printf("main_epic error\n"); @@ -1239,6 +1245,18 @@ index 0000000..1231b87 + printf("main_bitonic error\n"); + } + ++ clock_gettime(CLOCK_MONOTONIC, &end_ts); ++ long sec_diff = end_ts.tv_sec - start_ts.tv_sec; ++ long nsec_diff = end_ts.tv_nsec - start_ts.tv_nsec; ++ ++ if (nsec_diff < 0) ++ { ++ sec_diff -= 1; ++ nsec_diff += 1000000000; ++ } ++ ++ printf("%ld.%09ld seconds\n", sec_diff, nsec_diff); ++ + return 0; +} -- From 48fc61128c7c96a027a6b5c41844df75b8a359a2 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Wed, 16 Apr 2025 19:55:07 +0800 Subject: [PATCH 10/21] apps/ostest: Fix wqueue_test in flat mode. This commit re-enabled wqueue_test in flat mode. Signed-off-by: ouyangxiangzhen --- testing/ostest/ostest_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/ostest/ostest_main.c b/testing/ostest/ostest_main.c index 6bf75d86fed..4e2ca348400 100644 --- a/testing/ostest/ostest_main.c +++ b/testing/ostest/ostest_main.c @@ -381,7 +381,7 @@ static int user_main(int argc, char *argv[]) check_test_memory_usage(); #endif -#if !defined(CONFIG_DISABLE_PTHREAD) && defined(__KERNEL__) && \ +#if !defined(CONFIG_DISABLE_PTHREAD) && defined(CONFIG_BUILD_FLAT) && \ defined(CONFIG_SCHED_WORKQUEUE) /* Check work queues */ From f343dcf49f4ff173103f28a7fa3a95f7577cfac5 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Mon, 26 May 2025 21:07:14 +0800 Subject: [PATCH 11/21] ostest/wdog: Fix a synchronizing bug. If we updated `callback_cnt` before the `triggered_tick` in the wdog timer callback, the `wdtest_rand` might failed randomly. This commit fixed the synchronizing bug by swapping the execution order of updating. Signed-off-by: ouyangxiangzhen --- testing/ostest/wdog.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testing/ostest/wdog.c b/testing/ostest/wdog.c index 273a680e916..e64f1246fbb 100644 --- a/testing/ostest/wdog.c +++ b/testing/ostest/wdog.c @@ -70,13 +70,13 @@ static void wdtest_callback(wdparm_t param) { FAR wdtest_param_t *wdtest_param = (FAR wdtest_param_t *)param; - /* Increment the callback count */ - - wdtest_param->callback_cnt += 1; - /* Record the system tick at which the callback was triggered */ wdtest_param->triggered_tick = clock_systime_ticks(); + + /* Increment the callback count */ + + wdtest_param->callback_cnt += 1; } static void wdtest_checkdelay(sclock_t diff, sclock_t delay_tick) From 8e15ca1c9f37d52bd6365c0018a87c77ef1a2e95 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Tue, 2 Sep 2025 10:50:17 +0800 Subject: [PATCH 12/21] testing/drivers: Change uint32_t time to uint64_t. This commmit fixed the time multiplication overflow issue. Signed-off-by: ouyangxiangzhen --- testing/drivers/drivertest/drivertest_posix_timer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testing/drivers/drivertest/drivertest_posix_timer.c b/testing/drivers/drivertest/drivertest_posix_timer.c index 469ecc198b2..ccca6e1c296 100644 --- a/testing/drivers/drivertest/drivertest_posix_timer.c +++ b/testing/drivers/drivertest/drivertest_posix_timer.c @@ -64,7 +64,7 @@ struct posix_timer_state_s { struct itimerspec it; - uint32_t tim; + uint64_t tim; uint32_t deviation; }; @@ -140,12 +140,12 @@ static void parse_commandline( * Name: get_timestamp ****************************************************************************/ -static uint32_t get_timestamp(void) +static uint64_t get_timestamp(void) { struct timespec ts; - uint32_t ms; + uint64_t ms; clock_gettime(CLOCK_MONOTONIC, &ts); - ms = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; + ms = (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; return ms; } From 2605b0c865e256a6b7d3d9d9da9a8f83431f743d Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Tue, 2 Sep 2025 11:06:03 +0800 Subject: [PATCH 13/21] testing/drivers: Fix wrong test-cases. This commit fixed totally wrong test-cases for the periodical timers. Signed-off-by: ouyangxiangzhen --- testing/drivers/drivertest/drivertest_posix_timer.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/testing/drivers/drivertest/drivertest_posix_timer.c b/testing/drivers/drivertest/drivertest_posix_timer.c index ccca6e1c296..13eb4425abe 100644 --- a/testing/drivers/drivertest/drivertest_posix_timer.c +++ b/testing/drivers/drivertest/drivertest_posix_timer.c @@ -65,6 +65,7 @@ struct posix_timer_state_s { struct itimerspec it; uint64_t tim; + uint32_t trigger_count; uint32_t deviation; }; @@ -157,15 +158,16 @@ static void posix_timer_callback(union sigval arg) { FAR struct posix_timer_state_s *sigev_para = (FAR struct posix_timer_state_s *)arg.sival_ptr; - int range = get_timestamp() - (*sigev_para).tim; + uint64_t expected = (*sigev_para).tim + + DEFAULT_TIME_OUT * (*sigev_para).trigger_count; + int range = get_timestamp() - expected; syslog(0, "range: %d ms\n", range); - assert(range >= sigev_para->it.it_interval.tv_sec * 1000 - - sigev_para->deviation); + assert(range >= sigev_para->it.it_interval.tv_sec * 1000); syslog(LOG_DEBUG, "callback trigger!!!\n"); - (*sigev_para).tim = get_timestamp(); + (*sigev_para).trigger_count++; } /**************************************************************************** @@ -226,6 +228,7 @@ int main(int argc, FAR char *argv[]) .it.it_value.tv_nsec = 0, .it.it_interval.tv_sec = DEFAULT_TIME_OUT, .it.it_interval.tv_nsec = 0, + .trigger_count = 0, .deviation = RTC_DEFAULT_DEVIATION }; From 8eb9ea46035d6e03b23ee5fdf2e5c37675efe968 Mon Sep 17 00:00:00 2001 From: jiangtao16 Date: Fri, 20 Jun 2025 16:41:02 +0800 Subject: [PATCH 14/21] ostest: Add spinlock/rspinlock. This commit added spinlock/rspinlock test. Signed-off-by: jiangtao16 --- testing/ostest/CMakeLists.txt | 2 +- testing/ostest/Kconfig | 9 ++ testing/ostest/Makefile | 2 +- testing/ostest/ostest.h | 4 + testing/ostest/ostest_main.c | 4 + testing/ostest/spinlock.c | 184 ++++++++++++++++++++++++++++++++++ 6 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 testing/ostest/spinlock.c diff --git a/testing/ostest/CMakeLists.txt b/testing/ostest/CMakeLists.txt index 777c68744c1..35b0c5596e8 100644 --- a/testing/ostest/CMakeLists.txt +++ b/testing/ostest/CMakeLists.txt @@ -22,7 +22,7 @@ if(CONFIG_TESTING_OSTEST) - set(SRCS getopt.c libc_memmem.c restart.c sighelper.c) + set(SRCS getopt.c libc_memmem.c restart.c sighelper.c spinlock.c) if(CONFIG_ENABLE_ALL_SIGNALS) list(APPEND SRCS sighand.c signest.c) diff --git a/testing/ostest/Kconfig b/testing/ostest/Kconfig index 83054fa688a..100afb73e95 100644 --- a/testing/ostest/Kconfig +++ b/testing/ostest/Kconfig @@ -115,4 +115,13 @@ config TESTING_OSTEST_POWEROFF default n depends on BOARDCTL_POWEROFF && TESTING_OSTEST_WAITRESULT +config TESTING_OSTEST_SPINLOCK_THREADS + int "Number of spinlock test threads" + default 2 + range 1 32 + +config TEST_LOOP_SCALE + int "Loop scale of spinlock test (N x 10,000)" + default 100 + endif # TESTING_OSTEST diff --git a/testing/ostest/Makefile b/testing/ostest/Makefile index 1fedfcf54ee..b8be63a6268 100644 --- a/testing/ostest/Makefile +++ b/testing/ostest/Makefile @@ -31,7 +31,7 @@ MODULE = $(CONFIG_TESTING_OSTEST) # NuttX OS Test -CSRCS = getopt.c libc_memmem.c restart.c sighelper.c +CSRCS = getopt.c libc_memmem.c restart.c sighelper.c spinlock.c ifeq ($(CONFIG_ENABLE_ALL_SIGNALS),y) CSRCS += sighand.c signest.c diff --git a/testing/ostest/ostest.h b/testing/ostest/ostest.h index 321ecd2d330..1a396ba285c 100644 --- a/testing/ostest/ostest.h +++ b/testing/ostest/ostest.h @@ -286,6 +286,10 @@ void setjmp_test(void); void smp_call_test(void); #endif +/* spinlock.c ***************************************************************/ + +void spinlock_test(void); + /* APIs exported (conditionally) by the OS specifically for testing of * priority inheritance */ diff --git a/testing/ostest/ostest_main.c b/testing/ostest/ostest_main.c index 4e2ca348400..58ccc87fb2e 100644 --- a/testing/ostest/ostest_main.c +++ b/testing/ostest/ostest_main.c @@ -547,6 +547,10 @@ static int user_main(int argc, char *argv[]) #endif #endif + printf("\nuser_main: spinlock test\n"); + spinlock_test(); + check_test_memory_usage(); + #ifdef CONFIG_BUILD_FLAT printf("\nuser_main: wdog test\n"); wdog_test(); diff --git a/testing/ostest/spinlock.c b/testing/ostest/spinlock.c new file mode 100644 index 00000000000..2d71ea18f7b --- /dev/null +++ b/testing/ostest/spinlock.c @@ -0,0 +1,184 @@ +/**************************************************************************** + * apps/testing/ostest/spinlock.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 +#include +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Preprocessor Definitions + ****************************************************************************/ + +#define THREAD_NUM CONFIG_TESTING_OSTEST_SPINLOCK_THREADS +#define LOOP_TIMES (CONFIG_TEST_LOOP_SCALE * 10000) + +enum lock_type_e +{ + RSPINLOCK, + SPINLOCK +}; + +struct spinlock_pub_args_s +{ + volatile uint32_t counter; + pthread_barrier_t barrier; + union + { + rspinlock_t rlock; + spinlock_t lock; + }; +}; + +struct spinlock_thread_args_s +{ + uint64_t delta; + FAR struct spinlock_pub_args_s *pub; +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Helper functions for timespec calculating */ + +static inline uint64_t calc_diff(FAR struct timespec *start, + FAR struct timespec *end) +{ + uint64_t diff_sec = end->tv_sec - start->tv_sec; + long diff_nsec = end->tv_nsec - start->tv_nsec; + if (diff_nsec < 0) + { + diff_sec -= 1; + diff_nsec += 1000000000L; + } + + return diff_sec * 1000000000ULL + diff_nsec; +} + +#define LOCK_TEST_FUNC(lock_type, lock_func, unlock_func) \ +FAR static void * lock_type##_test_thread(FAR void *arg) \ +{ \ + struct spinlock_thread_args_s *param = \ + (struct spinlock_thread_args_s *)arg; \ + irqstate_t flags; \ + struct timespec start; \ + struct timespec end; \ + int i; \ + pthread_barrier_wait(¶m->pub->barrier); \ + clock_gettime(CLOCK_REALTIME, &start); \ + for (i = 0; i < LOOP_TIMES; i++) \ + { \ + flags = lock_func(¶m->pub->lock_type); \ + param->pub->counter++; \ + unlock_func(¶m->pub->lock_type, flags); \ + } \ + clock_gettime(CLOCK_REALTIME, &end); \ + param->delta = calc_diff(&start, &end); \ + return NULL; \ +} + +LOCK_TEST_FUNC(rlock, rspin_lock_irqsave, rspin_unlock_irqrestore) +LOCK_TEST_FUNC(lock, spin_lock_irqsave, spin_unlock_irqrestore) + +static inline void run_test_thread( + enum lock_type_e lock_type, + FAR void *(*thread_func)(FAR void *arg) + ) +{ + const char *test_type = (lock_type == RSPINLOCK) + ? "RSpin lock" : "Spin lock"; + printf("Test type: %s\n", test_type); + pthread_t tid[THREAD_NUM]; + struct spinlock_pub_args_s pub; + struct spinlock_thread_args_s param[THREAD_NUM]; + struct timespec stime; + struct timespec etime; + int i; + + pthread_barrier_init(&pub.barrier, NULL, THREAD_NUM + 1); + pub.counter = 0; + if (lock_type == RSPINLOCK) + { + rspin_lock_init(&pub.rlock); + } + else + { + spin_lock_init(&pub.lock); + } + + clock_gettime(CLOCK_REALTIME, &stime); + for (i = 0; i < THREAD_NUM; i++) + { + param[i].pub = &pub; + param[i].delta = 0; + pthread_create(&tid[i], NULL, thread_func, ¶m[i]); + } + + pthread_barrier_wait(&pub.barrier); + + for (i = 0; i < THREAD_NUM; i++) + { + pthread_join(tid[i], NULL); + } + + clock_gettime(CLOCK_REALTIME, &etime); + pthread_barrier_destroy(&pub.barrier); + uint64_t total_ns = 0; + for (i = 0; i < THREAD_NUM; i++) + { + total_ns += param[i].delta; + } + + printf("%s: Test Results:\n", test_type); + printf("%s: Final counter: %" PRIu32 "\n", test_type, pub.counter); + assert(pub.counter == THREAD_NUM * LOOP_TIMES); + printf("%s: Average time per thread: %" PRIu64 " ns\n" + , test_type, total_ns / THREAD_NUM); + printf("%s: Total execution time: %" PRIu64 " ns\n \n" + , test_type, calc_diff(&stime, &etime)); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spinlock_test + ****************************************************************************/ + +void spinlock_test(void) +{ + printf("Start Spin lock test:\n"); + printf("Thread num: %d, Loop times: %d\n\n", THREAD_NUM, LOOP_TIMES); + + run_test_thread(SPINLOCK, lock_test_thread); + + run_test_thread(RSPINLOCK, rlock_test_thread); +} From edfa547896bbbfa2bd763c7913073e9d49580e27 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 10 Jul 2025 11:05:42 +0800 Subject: [PATCH 15/21] testing/drivers: Fix posix timer assertions. On QEMU, if vcpus are preempted by other threads, the deviation of the timer might be very large, causing assertion failure. This commit addressed the problem. Signed-off-by: ouyangxiangzhen --- testing/drivers/drivertest/drivertest_posix_timer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testing/drivers/drivertest/drivertest_posix_timer.c b/testing/drivers/drivertest/drivertest_posix_timer.c index 13eb4425abe..65b95ee24c5 100644 --- a/testing/drivers/drivertest/drivertest_posix_timer.c +++ b/testing/drivers/drivertest/drivertest_posix_timer.c @@ -164,7 +164,8 @@ static void posix_timer_callback(union sigval arg) syslog(0, "range: %d ms\n", range); - assert(range >= sigev_para->it.it_interval.tv_sec * 1000); + assert(range >= sigev_para->it.it_interval.tv_sec * 1000 - + sigev_para->deviation); syslog(LOG_DEBUG, "callback trigger!!!\n"); (*sigev_para).trigger_count++; From d6f69d99b0b5cff52464badab79c2a22adb8cc3a Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Tue, 21 Oct 2025 17:47:59 +0800 Subject: [PATCH 16/21] ostest/spinlock: Check the return value. This commit added checking for the return value. Signed-off-by: ouyangxiangzhen --- testing/ostest/spinlock.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/testing/ostest/spinlock.c b/testing/ostest/spinlock.c index 2d71ea18f7b..dd49c4d544c 100644 --- a/testing/ostest/spinlock.c +++ b/testing/ostest/spinlock.c @@ -91,7 +91,7 @@ FAR static void * lock_type##_test_thread(FAR void *arg) \ struct timespec start; \ struct timespec end; \ int i; \ - pthread_barrier_wait(¶m->pub->barrier); \ + VERIFY(0 == pthread_barrier_wait(¶m->pub->barrier)); \ clock_gettime(CLOCK_REALTIME, &start); \ for (i = 0; i < LOOP_TIMES; i++) \ { \ @@ -122,7 +122,7 @@ static inline void run_test_thread( struct timespec etime; int i; - pthread_barrier_init(&pub.barrier, NULL, THREAD_NUM + 1); + VERIFY(0 == pthread_barrier_init(&pub.barrier, NULL, THREAD_NUM + 1)); pub.counter = 0; if (lock_type == RSPINLOCK) { @@ -141,7 +141,7 @@ static inline void run_test_thread( pthread_create(&tid[i], NULL, thread_func, ¶m[i]); } - pthread_barrier_wait(&pub.barrier); + VERIFY(0 == pthread_barrier_wait(&pub.barrier)); for (i = 0; i < THREAD_NUM; i++) { @@ -149,7 +149,8 @@ static inline void run_test_thread( } clock_gettime(CLOCK_REALTIME, &etime); - pthread_barrier_destroy(&pub.barrier); + VERIFY(0 == pthread_barrier_destroy(&pub.barrier)); + uint64_t total_ns = 0; for (i = 0; i < THREAD_NUM; i++) { From d83082360e274ed4d4f1131e40378133171c063b Mon Sep 17 00:00:00 2001 From: anpeiyun Date: Sun, 26 Oct 2025 11:38:14 +0800 Subject: [PATCH 17/21] ostest/spinlock: fix the operations does not affect the result. When expanding the macro VERIY, (0 == pthread_barrier_wait(¶m->pub->barrier)) < 0 always false. Regardless of the value of its operands. Signed-off-by: anpeiyun --- testing/ostest/spinlock.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/testing/ostest/spinlock.c b/testing/ostest/spinlock.c index dd49c4d544c..df691d7ca30 100644 --- a/testing/ostest/spinlock.c +++ b/testing/ostest/spinlock.c @@ -91,7 +91,12 @@ FAR static void * lock_type##_test_thread(FAR void *arg) \ struct timespec start; \ struct timespec end; \ int i; \ - VERIFY(0 == pthread_barrier_wait(¶m->pub->barrier)); \ + int ret; \ + ret = pthread_barrier_wait(¶m->pub->barrier); \ + if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) \ + { \ + ASSERT(false); \ + } \ clock_gettime(CLOCK_REALTIME, &start); \ for (i = 0; i < LOOP_TIMES; i++) \ { \ @@ -121,8 +126,14 @@ static inline void run_test_thread( struct timespec stime; struct timespec etime; int i; + int ret; + + ret = pthread_barrier_init(&pub.barrier, NULL, THREAD_NUM + 1); + if (ret != 0) + { + ASSERT(false); + } - VERIFY(0 == pthread_barrier_init(&pub.barrier, NULL, THREAD_NUM + 1)); pub.counter = 0; if (lock_type == RSPINLOCK) { @@ -141,7 +152,11 @@ static inline void run_test_thread( pthread_create(&tid[i], NULL, thread_func, ¶m[i]); } - VERIFY(0 == pthread_barrier_wait(&pub.barrier)); + ret = pthread_barrier_wait(&pub.barrier); + if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) + { + ASSERT(false); + } for (i = 0; i < THREAD_NUM; i++) { @@ -149,7 +164,11 @@ static inline void run_test_thread( } clock_gettime(CLOCK_REALTIME, &etime); - VERIFY(0 == pthread_barrier_destroy(&pub.barrier)); + ret = pthread_barrier_destroy(&pub.barrier); + if (ret != 0) + { + ASSERT(false); + } uint64_t total_ns = 0; for (i = 0; i < THREAD_NUM; i++) From 19606dcf0876a1918a4d61099d1994e0f1799c9e Mon Sep 17 00:00:00 2001 From: anpeiyun Date: Sun, 26 Oct 2025 11:29:33 +0800 Subject: [PATCH 18/21] ostest/spinlock: Check the return value. This commit added checking for the return value. Signed-off-by: anpeiyun --- testing/ostest/spinlock.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/testing/ostest/spinlock.c b/testing/ostest/spinlock.c index df691d7ca30..7d66b64b65b 100644 --- a/testing/ostest/spinlock.c +++ b/testing/ostest/spinlock.c @@ -149,7 +149,11 @@ static inline void run_test_thread( { param[i].pub = &pub; param[i].delta = 0; - pthread_create(&tid[i], NULL, thread_func, ¶m[i]); + ret = pthread_create(&tid[i], NULL, thread_func, ¶m[i]); + if (ret != 0) + { + ASSERT(false); + } } ret = pthread_barrier_wait(&pub.barrier); From fe0f0a28d5250fc1e190eac426f9a8c6ce9d6b26 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Fri, 7 Nov 2025 09:52:20 +0800 Subject: [PATCH 19/21] testing/ostest: refactor the spinlock test. This commit refactored the spinlock test for better accuracy and minimized jitters introduced by scheduling. Signed-off-by: ouyangxiangzhen --- testing/ostest/spinlock.c | 201 ++++++++++++++++++++++++-------------- 1 file changed, 129 insertions(+), 72 deletions(-) diff --git a/testing/ostest/spinlock.c b/testing/ostest/spinlock.c index 7d66b64b65b..0e38ec03bbc 100644 --- a/testing/ostest/spinlock.c +++ b/testing/ostest/spinlock.c @@ -30,30 +30,23 @@ #include #include #include +#include #include +#include /**************************************************************************** * Preprocessor Definitions ****************************************************************************/ -#define THREAD_NUM CONFIG_TESTING_OSTEST_SPINLOCK_THREADS -#define LOOP_TIMES (CONFIG_TEST_LOOP_SCALE * 10000) +#define MAX_THREAD_NUM (CONFIG_SMP_NCPUS) +#define LOOP_TIMES (CONFIG_TEST_LOOP_SCALE * 100000) -enum lock_type_e -{ - RSPINLOCK, - SPINLOCK -}; - -struct spinlock_pub_args_s +aligned_data(64) struct spinlock_pub_args_s { + FAR void *lock; volatile uint32_t counter; - pthread_barrier_t barrier; - union - { - rspinlock_t rlock; - spinlock_t lock; - }; + atomic_t barrier; + uint32_t thread_num; }; struct spinlock_thread_args_s @@ -90,103 +83,145 @@ FAR static void * lock_type##_test_thread(FAR void *arg) \ irqstate_t flags; \ struct timespec start; \ struct timespec end; \ - int i; \ - int ret; \ - ret = pthread_barrier_wait(¶m->pub->barrier); \ - if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) \ + uint32_t i; \ + FAR struct spinlock_pub_args_s *pub = param->pub; \ + FAR lock_type *l = (FAR lock_type *)pub->lock; \ + atomic_fetch_add(&pub->barrier, 1); \ + while (atomic_read(&pub->barrier) != pub->thread_num) \ { \ - ASSERT(false); \ + sched_yield(); \ } \ clock_gettime(CLOCK_REALTIME, &start); \ for (i = 0; i < LOOP_TIMES; i++) \ { \ - flags = lock_func(¶m->pub->lock_type); \ - param->pub->counter++; \ - unlock_func(¶m->pub->lock_type, flags); \ + flags = lock_func(l); \ + pub->counter++; \ + unlock_func(l, flags); \ } \ clock_gettime(CLOCK_REALTIME, &end); \ param->delta = calc_diff(&start, &end); \ return NULL; \ } -LOCK_TEST_FUNC(rlock, rspin_lock_irqsave, rspin_unlock_irqrestore) -LOCK_TEST_FUNC(lock, spin_lock_irqsave, spin_unlock_irqrestore) +LOCK_TEST_FUNC(spinlock_t, spin_lock_irqsave, spin_unlock_irqrestore) +LOCK_TEST_FUNC(rspinlock_t, rspin_lock_irqsave, rspin_unlock_irqrestore) +LOCK_TEST_FUNC(seqcount_t, write_seqlock_irqsave, write_sequnlock_irqrestore) -static inline void run_test_thread( - enum lock_type_e lock_type, - FAR void *(*thread_func)(FAR void *arg) - ) +static inline +void run_test_thread(void *lock, FAR void *(*thread_func)(FAR void *arg), + uint32_t thread_num, const char *lock_type) { - const char *test_type = (lock_type == RSPINLOCK) - ? "RSpin lock" : "Spin lock"; - printf("Test type: %s\n", test_type); - pthread_t tid[THREAD_NUM]; + pthread_t tid[MAX_THREAD_NUM]; struct spinlock_pub_args_s pub; - struct spinlock_thread_args_s param[THREAD_NUM]; + pthread_attr_t attr; + struct sched_param sparam; + struct spinlock_thread_args_s param[MAX_THREAD_NUM]; struct timespec stime; struct timespec etime; + cpu_set_t cpu_set = 1u; + uint64_t total_ns = 0u; + int status; int i; - int ret; - ret = pthread_barrier_init(&pub.barrier, NULL, THREAD_NUM + 1); - if (ret != 0) + /* Initialize the public parameters. */ + + printf("Test type: %s\n", lock_type); + + pub.lock = lock; + pub.counter = 0u; + pub.thread_num = thread_num; + atomic_set_release(&pub.barrier, 0u); + + /* Set affinity to CPU0 */ + +#ifdef CONFIG_SMP + if (OK != sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpu_set)) { + printf("spinlock_test: ERROR: nxsched_set_affinity failed"); ASSERT(false); } +#else + UNUSED(cpu_set); +#endif + + /* Boost to maximum priority for test threads. */ - pub.counter = 0; - if (lock_type == RSPINLOCK) + status = pthread_attr_init(&attr); + if (status != 0) { - rspin_lock_init(&pub.rlock); + printf("spinlock_test: ERROR: " + "pthread_attr_init failed, status=%d\n", status); + ASSERT(false); } - else + + sparam.sched_priority = SCHED_PRIORITY_MAX; + status = pthread_attr_setschedparam(&attr, &sparam); + if (status != OK) { - spin_lock_init(&pub.lock); + printf("spinlock_test: ERROR: " + "pthread_attr_setschedparam failed, status=%d\n", status); + ASSERT(false); } clock_gettime(CLOCK_REALTIME, &stime); - for (i = 0; i < THREAD_NUM; i++) + + /* Create new test threads. */ + + for (i = 0; i < thread_num; i++) { param[i].pub = &pub; param[i].delta = 0; - ret = pthread_create(&tid[i], NULL, thread_func, ¶m[i]); - if (ret != 0) + + /* Set affinity */ + +#ifdef CONFIG_SMP + cpu_set = 1u << ((i + 1) % CONFIG_SMP_NCPUS); + + status = pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), + &cpu_set); + if (status != OK) { + printf("spinlock_test: ERROR: " + "pthread_attr_setaffinity_np failed, status=%d\n", status); ASSERT(false); } - } +#endif - ret = pthread_barrier_wait(&pub.barrier); - if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) - { - ASSERT(false); + status = pthread_create(&tid[i], &attr, thread_func, ¶m[i]); + if (status != 0) + { + printf("spinlock_test: ERROR: " + "pthread_create failed, status=%d\n", status); + ASSERT(false); + } } - for (i = 0; i < THREAD_NUM; i++) + for (i = 0; i < thread_num; i++) { - pthread_join(tid[i], NULL); + status = pthread_join(tid[i], NULL); + if (status != 0) + { + printf("spinlock_test: ERROR: " + "pthread_join failed, status=%d\n", status); + ASSERT(false); + } } - clock_gettime(CLOCK_REALTIME, &etime); - ret = pthread_barrier_destroy(&pub.barrier); - if (ret != 0) - { - ASSERT(false); - } + /* Calculate the average throughput. */ - uint64_t total_ns = 0; - for (i = 0; i < THREAD_NUM; i++) + clock_gettime(CLOCK_REALTIME, &etime); + for (i = 0; i < thread_num; i++) { total_ns += param[i].delta; } - printf("%s: Test Results:\n", test_type); - printf("%s: Final counter: %" PRIu32 "\n", test_type, pub.counter); - assert(pub.counter == THREAD_NUM * LOOP_TIMES); - printf("%s: Average time per thread: %" PRIu64 " ns\n" - , test_type, total_ns / THREAD_NUM); - printf("%s: Total execution time: %" PRIu64 " ns\n \n" - , test_type, calc_diff(&stime, &etime)); + printf("%s: Test Results:\n", lock_type); + printf("%s: Final counter: %" PRIu32 "\n", lock_type, pub.counter); + assert(pub.counter == thread_num * LOOP_TIMES); + printf("%s: Average throughput : %" PRIu64 " op/s\n", lock_type, + (uint64_t)NSEC_PER_SEC * LOOP_TIMES * thread_num / total_ns); + printf("%s: Total execution time: %" PRIu64 " ns\n \n", + lock_type, calc_diff(&stime, &etime)); } /**************************************************************************** @@ -197,12 +232,34 @@ static inline void run_test_thread( * Name: spinlock_test ****************************************************************************/ -void spinlock_test(void) +static void spinlock_test_thread_num(unsigned thread_num) { - printf("Start Spin lock test:\n"); - printf("Thread num: %d, Loop times: %d\n\n", THREAD_NUM, LOOP_TIMES); + aligned_data(64) union + { + spinlock_t spinlock; + rspinlock_t rspinlock; + seqcount_t seqcount; + } lock; + + printf("Start Lock test:\n"); + printf("Thread num: %u, Loop times: %d\n\n", thread_num, LOOP_TIMES); + + spin_lock_init(&lock.spinlock); + run_test_thread(&lock, spinlock_t_test_thread, thread_num, "spinlock"); + + rspin_lock_init(&lock.rspinlock); + run_test_thread(&lock, rspinlock_t_test_thread, thread_num, "rspinlock"); + + seqlock_init(&lock.seqcount); + run_test_thread(&lock, seqcount_t_test_thread, thread_num, "seqcount"); +} - run_test_thread(SPINLOCK, lock_test_thread); +void spinlock_test(void) +{ + unsigned tnr; - run_test_thread(RSPINLOCK, rlock_test_thread); + for (tnr = 1; tnr < MAX_THREAD_NUM; tnr++) + { + spinlock_test_thread_num(tnr); + } } From 4253152759832a21d1b3829b3e23366e8ac9282b Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Tue, 30 Dec 2025 10:07:46 +0800 Subject: [PATCH 20/21] testing/ostest: Fix Coverity for spinlock test. This commit fixed coverity for spinlock test. Signed-off-by: ouyangxiangzhen --- testing/ostest/spinlock.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/testing/ostest/spinlock.c b/testing/ostest/spinlock.c index 0e38ec03bbc..1ebe290f1d9 100644 --- a/testing/ostest/spinlock.c +++ b/testing/ostest/spinlock.c @@ -215,13 +215,20 @@ void run_test_thread(void *lock, FAR void *(*thread_func)(FAR void *arg), total_ns += param[i].delta; } - printf("%s: Test Results:\n", lock_type); - printf("%s: Final counter: %" PRIu32 "\n", lock_type, pub.counter); - assert(pub.counter == thread_num * LOOP_TIMES); - printf("%s: Average throughput : %" PRIu64 " op/s\n", lock_type, - (uint64_t)NSEC_PER_SEC * LOOP_TIMES * thread_num / total_ns); - printf("%s: Total execution time: %" PRIu64 " ns\n \n", - lock_type, calc_diff(&stime, &etime)); + if (total_ns != 0) + { + printf("%s: Test Results:\n", lock_type); + printf("%s: Final counter: %" PRIu32 "\n", lock_type, pub.counter); + assert(pub.counter == thread_num * LOOP_TIMES); + printf("%s: Average throughput : %" PRIu64 " op/s\n", lock_type, + (uint64_t)NSEC_PER_SEC * LOOP_TIMES * thread_num / total_ns); + printf("%s: Total execution time: %" PRIu64 " ns\n \n", + lock_type, calc_diff(&stime, &etime)); + } + else + { + printf("spinlock_test: ERROR: total_ns is 0\n"); + } } /**************************************************************************** @@ -258,7 +265,7 @@ void spinlock_test(void) { unsigned tnr; - for (tnr = 1; tnr < MAX_THREAD_NUM; tnr++) + for (tnr = 1; tnr <= MAX_THREAD_NUM; tnr++) { spinlock_test_thread_num(tnr); } From 0ae2a279b02264ce2e0e56ae92ec466a80285e40 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Tue, 27 Jan 2026 17:49:19 +0800 Subject: [PATCH 21/21] testing/ostest: run spinlock_test only in flat mode. Since the kernel spinlocks can only work in flat mode, this commit allowed spinlock_test only in flat mode. Signed-off-by: ouyangxiangzhen --- testing/ostest/CMakeLists.txt | 4 ++-- testing/ostest/Makefile | 4 ++-- testing/ostest/ostest_main.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/testing/ostest/CMakeLists.txt b/testing/ostest/CMakeLists.txt index 35b0c5596e8..a8a2ca9211e 100644 --- a/testing/ostest/CMakeLists.txt +++ b/testing/ostest/CMakeLists.txt @@ -22,7 +22,7 @@ if(CONFIG_TESTING_OSTEST) - set(SRCS getopt.c libc_memmem.c restart.c sighelper.c spinlock.c) + set(SRCS getopt.c libc_memmem.c restart.c sighelper.c) if(CONFIG_ENABLE_ALL_SIGNALS) list(APPEND SRCS sighand.c signest.c) @@ -162,7 +162,7 @@ if(CONFIG_TESTING_OSTEST) endif() if(CONFIG_BUILD_FLAT) - list(APPEND SRCS wdog.c) + list(APPEND SRCS wdog.c spinlock.c) endif() set(OSTEST_SRCS ostest_main.c ${SRCS}) diff --git a/testing/ostest/Makefile b/testing/ostest/Makefile index b8be63a6268..817fcdb51d4 100644 --- a/testing/ostest/Makefile +++ b/testing/ostest/Makefile @@ -31,7 +31,7 @@ MODULE = $(CONFIG_TESTING_OSTEST) # NuttX OS Test -CSRCS = getopt.c libc_memmem.c restart.c sighelper.c spinlock.c +CSRCS = getopt.c libc_memmem.c restart.c sighelper.c ifeq ($(CONFIG_ENABLE_ALL_SIGNALS),y) CSRCS += sighand.c signest.c @@ -167,7 +167,7 @@ endif endif ifeq ($(CONFIG_BUILD_FLAT),y) -CSRCS += wdog.c +CSRCS += wdog.c spinlock.c endif include $(APPDIR)/Application.mk diff --git a/testing/ostest/ostest_main.c b/testing/ostest/ostest_main.c index 58ccc87fb2e..8247b47883b 100644 --- a/testing/ostest/ostest_main.c +++ b/testing/ostest/ostest_main.c @@ -547,11 +547,11 @@ static int user_main(int argc, char *argv[]) #endif #endif +#ifdef CONFIG_BUILD_FLAT printf("\nuser_main: spinlock test\n"); spinlock_test(); check_test_memory_usage(); -#ifdef CONFIG_BUILD_FLAT printf("\nuser_main: wdog test\n"); wdog_test(); check_test_memory_usage();