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:
Andy Ross 2018-02-02 13:49:30 -08:00 committed by Anas Nashif
commit 59cdfe6e44
4 changed files with 90 additions and 0 deletions

View 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)

View file

@ -0,0 +1,2 @@
CONFIG_ZTEST=y
CONFIG_SMP=y

View 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);
}
}

View file

@ -0,0 +1,3 @@
tests:
test:
platform_whitelist: esp32