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:
Sergio Rodriguez 2016-12-20 18:16:43 -08:00 committed by Anas Nashif
commit 5fbb695a01
6 changed files with 260 additions and 0 deletions

View file

@ -0,0 +1,4 @@
BOARD ?= qemu_x86
CONF_FILE = prj.conf
include ${ZEPHYR_BASE}/Makefile.inc

View 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

View file

@ -0,0 +1,2 @@
CONFIG_NUM_TASK_PRIORITIES=50
CONFIG_ZTEST=y

View file

@ -0,0 +1,4 @@
ccflags-y += -I${ZEPHYR_BASE}/tests/include
include $(ZEPHYR_BASE)/tests/Makefile.test
obj-y = critical.o

View 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(&REGRESS_SEM);
k_sem_take(&ALT_SEM, K_FOREVER); /* Wait to be re-activated */
altTaskIterations = criticalLoop(altTaskIterations);
k_sem_give(&REGRESS_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(&REGRESS_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(&REGRESS_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);
}

View file

@ -0,0 +1,2 @@
[test]
tags = core bat_commit