tests: kernel: test_critical: Porting legacy tests to unified kernel
This is the port of the legacy/kernel/test_critical test case to the unified kernel, and to use the ztest framework Change-Id: I10834cbb51446b4a12fc680c0b65438d550f4d85 Signed-off-by: Sergio Rodriguez <sergio.sf.rodriguez@intel.com> Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
a6a1360b24
commit
5fbb695a01
6 changed files with 260 additions and 0 deletions
4
tests/kernel/critical/Makefile
Normal file
4
tests/kernel/critical/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
BOARD ?= qemu_x86
|
||||||
|
CONF_FILE = prj.conf
|
||||||
|
|
||||||
|
include ${ZEPHYR_BASE}/Makefile.inc
|
48
tests/kernel/critical/README.txt
Normal file
48
tests/kernel/critical/README.txt
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
Title: Offload to the Kernel offload workqueue
|
||||||
|
|
||||||
|
Description:
|
||||||
|
|
||||||
|
This test verifies that the kernel offload workqueue operates as
|
||||||
|
expected.
|
||||||
|
|
||||||
|
This test has two tasks that increment a counter. The routine that
|
||||||
|
increments the counter is invoked from workqueue due to the two tasks
|
||||||
|
calling using it. The final result of the counter is expected
|
||||||
|
to be the the number of times work item was called to increment
|
||||||
|
the counter.
|
||||||
|
|
||||||
|
This is done with time slicing both disabled and enabled to ensure that the
|
||||||
|
result always matches the number of times the workqueue is called.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Building and Running Project:
|
||||||
|
|
||||||
|
This microkernel project outputs to the console. It can be built and executed
|
||||||
|
on QEMU as follows:
|
||||||
|
|
||||||
|
make qemu
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Troubleshooting:
|
||||||
|
|
||||||
|
Problems caused by out-dated project information can be addressed by
|
||||||
|
issuing one of the following commands then rebuilding the project:
|
||||||
|
|
||||||
|
make clean # discard results of previous builds
|
||||||
|
# but keep existing configuration info
|
||||||
|
or
|
||||||
|
make pristine # discard results of previous builds
|
||||||
|
# and restore pre-defined configuration info
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Sample Output:
|
||||||
|
|
||||||
|
Running test suite kernel_critical_test
|
||||||
|
tc_start() - test_critical
|
||||||
|
===================================================================
|
||||||
|
PASS - test_critical.
|
||||||
|
===================================================================
|
||||||
|
PROJECT EXECUTION SUCCESSFUL
|
2
tests/kernel/critical/prj.conf
Normal file
2
tests/kernel/critical/prj.conf
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
CONFIG_NUM_TASK_PRIORITIES=50
|
||||||
|
CONFIG_ZTEST=y
|
4
tests/kernel/critical/src/Makefile
Normal file
4
tests/kernel/critical/src/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
ccflags-y += -I${ZEPHYR_BASE}/tests/include
|
||||||
|
include $(ZEPHYR_BASE)/tests/Makefile.test
|
||||||
|
|
||||||
|
obj-y = critical.o
|
200
tests/kernel/critical/src/critical.c
Normal file
200
tests/kernel/critical/src/critical.c
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
/* critical.c - test the offload workqueue API */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014 Wind River Systems, Inc.
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DESCRIPTION
|
||||||
|
* This module tests the offload workqueue.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr.h>
|
||||||
|
#include <sections.h>
|
||||||
|
#include <ztest.h>
|
||||||
|
|
||||||
|
#define NUM_MILLISECONDS 5000
|
||||||
|
#define TEST_TIMEOUT 20000
|
||||||
|
|
||||||
|
static uint32_t criticalVar;
|
||||||
|
static uint32_t altTaskIterations;
|
||||||
|
|
||||||
|
static struct k_work_q offload_work_q;
|
||||||
|
static char __stack offload_work_q_stack[CONFIG_OFFLOAD_WORKQUEUE_STACK_SIZE];
|
||||||
|
|
||||||
|
#define STACK_SIZE 1024
|
||||||
|
static char __stack stack1[STACK_SIZE];
|
||||||
|
static char __stack stack2[STACK_SIZE];
|
||||||
|
|
||||||
|
K_SEM_DEFINE(ALT_SEM, 0, UINT_MAX);
|
||||||
|
K_SEM_DEFINE(REGRESS_SEM, 0, UINT_MAX);
|
||||||
|
K_SEM_DEFINE(TEST_SEM, 0, UINT_MAX);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Routine to be called from a workqueue
|
||||||
|
*
|
||||||
|
* This routine increments the global variable <criticalVar>.
|
||||||
|
*
|
||||||
|
* @return 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
void criticalRtn(struct k_work *unused)
|
||||||
|
{
|
||||||
|
volatile uint32_t x;
|
||||||
|
|
||||||
|
ARG_UNUSED(unused);
|
||||||
|
|
||||||
|
x = criticalVar;
|
||||||
|
criticalVar = x + 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Common code for invoking offload work
|
||||||
|
*
|
||||||
|
* @param count number of critical section calls made thus far
|
||||||
|
*
|
||||||
|
* @return number of critical section calls made by task
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32_t criticalLoop(uint32_t count)
|
||||||
|
{
|
||||||
|
int64_t mseconds;
|
||||||
|
|
||||||
|
mseconds = k_uptime_get();
|
||||||
|
while (k_uptime_get() < mseconds + NUM_MILLISECONDS) {
|
||||||
|
struct k_work work_item;
|
||||||
|
|
||||||
|
k_work_init(&work_item, criticalRtn);
|
||||||
|
k_work_submit_to_queue(&offload_work_q, &work_item);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Alternate task
|
||||||
|
*
|
||||||
|
* This routine invokes the workqueue many times.
|
||||||
|
*
|
||||||
|
* @return N/A
|
||||||
|
*/
|
||||||
|
|
||||||
|
void AlternateTask(void *arg1, void *arg2, void *arg3)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(arg1);
|
||||||
|
ARG_UNUSED(arg2);
|
||||||
|
ARG_UNUSED(arg3);
|
||||||
|
|
||||||
|
k_sem_take(&ALT_SEM, K_FOREVER); /* Wait to be activated */
|
||||||
|
|
||||||
|
altTaskIterations = criticalLoop(altTaskIterations);
|
||||||
|
|
||||||
|
k_sem_give(®RESS_SEM);
|
||||||
|
|
||||||
|
k_sem_take(&ALT_SEM, K_FOREVER); /* Wait to be re-activated */
|
||||||
|
|
||||||
|
altTaskIterations = criticalLoop(altTaskIterations);
|
||||||
|
|
||||||
|
k_sem_give(®RESS_SEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Regression task
|
||||||
|
*
|
||||||
|
* This routine calls invokes the workqueue many times. It also checks to
|
||||||
|
* ensure that the number of times it is called matches the global variable
|
||||||
|
* <criticalVar>.
|
||||||
|
*
|
||||||
|
* @return N/A
|
||||||
|
*/
|
||||||
|
|
||||||
|
void RegressionTask(void *arg1, void *arg2, void *arg3)
|
||||||
|
{
|
||||||
|
uint32_t nCalls = 0;
|
||||||
|
|
||||||
|
ARG_UNUSED(arg1);
|
||||||
|
ARG_UNUSED(arg2);
|
||||||
|
ARG_UNUSED(arg3);
|
||||||
|
|
||||||
|
k_sem_give(&ALT_SEM); /* Activate AlternateTask() */
|
||||||
|
|
||||||
|
nCalls = criticalLoop(nCalls);
|
||||||
|
|
||||||
|
/* Wait for AlternateTask() to complete */
|
||||||
|
assert_true(k_sem_take(®RESS_SEM, TEST_TIMEOUT) == 0,
|
||||||
|
"Timed out waiting for REGRESS_SEM");
|
||||||
|
|
||||||
|
assert_equal(criticalVar, nCalls + altTaskIterations,
|
||||||
|
"Unexpected value for <criticalVar>");
|
||||||
|
|
||||||
|
k_sched_time_slice_set(10, 10);
|
||||||
|
|
||||||
|
k_sem_give(&ALT_SEM); /* Re-activate AlternateTask() */
|
||||||
|
|
||||||
|
nCalls = criticalLoop(nCalls);
|
||||||
|
|
||||||
|
/* Wait for AlternateTask() to finish */
|
||||||
|
assert_true(k_sem_take(®RESS_SEM, TEST_TIMEOUT) == 0,
|
||||||
|
"Timed out waiting for REGRESS_SEM");
|
||||||
|
|
||||||
|
assert_equal(criticalVar, nCalls + altTaskIterations,
|
||||||
|
"Unexpected value for <criticalVar>");
|
||||||
|
|
||||||
|
k_sem_give(&TEST_SEM);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_objects(void)
|
||||||
|
{
|
||||||
|
criticalVar = 0;
|
||||||
|
altTaskIterations = 0;
|
||||||
|
k_work_q_start(&offload_work_q,
|
||||||
|
offload_work_q_stack,
|
||||||
|
sizeof(offload_work_q_stack),
|
||||||
|
CONFIG_OFFLOAD_WORKQUEUE_PRIORITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void start_threads(void)
|
||||||
|
{
|
||||||
|
k_thread_spawn(stack1, STACK_SIZE,
|
||||||
|
AlternateTask, NULL, NULL, NULL,
|
||||||
|
K_PRIO_PREEMPT(12), 0, 0);
|
||||||
|
|
||||||
|
k_thread_spawn(stack2, STACK_SIZE,
|
||||||
|
RegressionTask, NULL, NULL, NULL,
|
||||||
|
K_PRIO_PREEMPT(12), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_critical(void)
|
||||||
|
{
|
||||||
|
init_objects();
|
||||||
|
start_threads();
|
||||||
|
|
||||||
|
assert_true(k_sem_take(&TEST_SEM, TEST_TIMEOUT * 2) == 0,
|
||||||
|
"Timed out waiting for TEST_SEM");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_main(void)
|
||||||
|
{
|
||||||
|
ztest_test_suite(kernel_critical_test, ztest_unit_test(test_critical));
|
||||||
|
|
||||||
|
ztest_run_test_suite(kernel_critical_test);
|
||||||
|
}
|
2
tests/kernel/critical/testcase.ini
Normal file
2
tests/kernel/critical/testcase.ini
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[test]
|
||||||
|
tags = core bat_commit
|
Loading…
Add table
Add a link
Reference in a new issue