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 <andrew.j.ross@intel.com>
This commit is contained in:
parent
564f59060c
commit
59cdfe6e44
4 changed files with 90 additions and 0 deletions
4
tests/kernel/smp/CMakeLists.txt
Normal file
4
tests/kernel/smp/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
|
||||
project(NONE)
|
||||
|
||||
target_sources(app PRIVATE src/main.c)
|
2
tests/kernel/smp/prj.conf
Normal file
2
tests/kernel/smp/prj.conf
Normal file
|
@ -0,0 +1,2 @@
|
|||
CONFIG_ZTEST=y
|
||||
CONFIG_SMP=y
|
81
tests/kernel/smp/src/main.c
Normal file
81
tests/kernel/smp/src/main.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <tc_util.h>
|
||||
#include <ztest.h>
|
||||
#include <kernel.h>
|
||||
#include <kernel_structs.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
3
tests/kernel/smp/testcase.yaml
Normal file
3
tests/kernel/smp/testcase.yaml
Normal file
|
@ -0,0 +1,3 @@
|
|||
tests:
|
||||
test:
|
||||
platform_whitelist: esp32
|
Loading…
Add table
Add a link
Reference in a new issue