From 59cdfe6e441cd670780bc25b0ef63ef1e4afbff3 Mon Sep 17 00:00:00 2001 From: Andy Ross Date: Fri, 2 Feb 2018 13:49:30 -0800 Subject: [PATCH] tests/kernel: SMP test Simple SMP test to validate the two threads can be simultaneously scheduled. Arranges things such that both threads are at different priorities and never yield the CPU, so on a uniprocessor build they cannot be fairly scheduled. Checks that both are nonetheless making progress. Signed-off-by: Andy Ross --- tests/kernel/smp/CMakeLists.txt | 4 ++ tests/kernel/smp/prj.conf | 2 + tests/kernel/smp/src/main.c | 81 +++++++++++++++++++++++++++++++++ tests/kernel/smp/testcase.yaml | 3 ++ 4 files changed, 90 insertions(+) create mode 100644 tests/kernel/smp/CMakeLists.txt create mode 100644 tests/kernel/smp/prj.conf create mode 100644 tests/kernel/smp/src/main.c create mode 100644 tests/kernel/smp/testcase.yaml diff --git a/tests/kernel/smp/CMakeLists.txt b/tests/kernel/smp/CMakeLists.txt new file mode 100644 index 00000000000..6daa0b7cc76 --- /dev/null +++ b/tests/kernel/smp/CMakeLists.txt @@ -0,0 +1,4 @@ +include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE) +project(NONE) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/kernel/smp/prj.conf b/tests/kernel/smp/prj.conf new file mode 100644 index 00000000000..26542e0a35c --- /dev/null +++ b/tests/kernel/smp/prj.conf @@ -0,0 +1,2 @@ +CONFIG_ZTEST=y +CONFIG_SMP=y diff --git a/tests/kernel/smp/src/main.c b/tests/kernel/smp/src/main.c new file mode 100644 index 00000000000..822b39f22d1 --- /dev/null +++ b/tests/kernel/smp/src/main.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2018 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#if CONFIG_MP_NUM_CPUS < 2 +#error SMP test requires at least two CPUs! +#endif + +#define T2_STACK_SIZE 2048 + +K_THREAD_STACK_DEFINE(t2_stack, T2_STACK_SIZE); + +struct k_thread t2; + +volatile int t2_count; + +#define DELAY_US 50000 + +void t2_fn(void *a, void *b, void *c) +{ + ARG_UNUSED(a); + ARG_UNUSED(b); + ARG_UNUSED(c); + + /* This thread simply increments a counter while spinning on + * the CPU. The idea is that it will always be iterating + * faster than the other thread so long as it is fairly + * scheduled (and it's designed to NOT be fairly schedulable + * without a separate CPU!), so the main thread can always + * check its progress. + */ + while (1) { + k_busy_wait(DELAY_US); + t2_count++; + } +} + +void test_main(void) +{ + int i, ok = 1; + + /* Sleep a bit to guarantee that both CPUs enter an idle + * thread from which they can exit correctly to run the main + * test. + */ + k_sleep(100); + + /* Create a thread at a fixed priority lower than the main + * thread. In uniprocessor mode, this thread will never be + * scheduled and the test will fail. + */ + k_thread_create(&t2, t2_stack, T2_STACK_SIZE, t2_fn, + NULL, NULL, NULL, + CONFIG_MAIN_THREAD_PRIORITY + 1, 0, K_NO_WAIT); + + for (i = 0; i < 10; i++) { + /* Wait slightly longer than the other thread so our + * count will always be lower + */ + k_busy_wait(DELAY_US + (DELAY_US / 8)); + + if (t2_count <= i) { + ok = 0; + break; + } + } + + if (ok) { + TC_END_REPORT(TC_PASS); + } else { + TC_END_REPORT(TC_FAIL); + } +} diff --git a/tests/kernel/smp/testcase.yaml b/tests/kernel/smp/testcase.yaml new file mode 100644 index 00000000000..5523f73ef27 --- /dev/null +++ b/tests/kernel/smp/testcase.yaml @@ -0,0 +1,3 @@ +tests: + test: + platform_whitelist: esp32