tests: benchmark: sys_kernel: Porting to unified

This change ports tests/legacy/benchmark/sys_kernel stuff to
use unified APIs.

Change-Id: If6fbaa5586502205e9f4dc6e79ff1c1a1c1b8102
Signed-off-by: Jithu Joseph <jithu.joseph@intel.com>
This commit is contained in:
Jithu Joseph 2017-01-12 12:56:40 -08:00 committed by Anas Nashif
commit b636625a2b
11 changed files with 1408 additions and 0 deletions

View file

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

View file

@ -0,0 +1,177 @@
Title: kernel Object Performance
Description:
The SysKernel test measures the performance of semaphore,
lifo, fifo and stack objects.
--------------------------------------------------------------------------------
Building and Running Project:
This 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:
MODULE: kernel API test
KERNEL VERSION: 0x1066300
Each test below is repeated 5000 times;
average time for one iteration is displayed.
TEST CASE: Semaphore #1
TEST COVERAGE:
k_sem_init
k_sem_take(TICKS_UNLIMITED)
k_sem_give
Starting test. Please wait...
TEST RESULT: SUCCESSFUL
DETAILS: Average time for 1 iteration: NNNN nSec
END TEST CASE
TEST CASE: Semaphore #2
TEST COVERAGE:
k_sem_init
k_sem_take(TICKS_NONE)
k_yield
k_sem_give
Starting test. Please wait...
TEST RESULT: SUCCESSFUL
DETAILS: Average time for 1 iteration: NNNN nSec
END TEST CASE
TEST CASE: Semaphore #3
TEST COVERAGE:
k_sem_init
k_sem_take(TICKS_UNLIMITED)
k_sem_give
k_sem_give
k_sem_take(TICKS_UNLIMITED)
Starting test. Please wait...
TEST RESULT: SUCCESSFUL
DETAILS: Average time for 1 iteration: NNNN nSec
END TEST CASE
TEST CASE: LIFO #1
TEST COVERAGE:
k_lifo_init
k_lifo_get(K_FOREVER)
k_lifo_put
Starting test. Please wait...
TEST RESULT: SUCCESSFUL
DETAILS: Average time for 1 iteration: NNNN nSec
END TEST CASE
TEST CASE: LIFO #2
TEST COVERAGE:
k_lifo_init
k_lifo_get(K_FOREVER)
k_lifo_get(TICKS_NONE)
k_lifo_put
k_yield
Starting test. Please wait...
TEST RESULT: SUCCESSFUL
DETAILS: Average time for 1 iteration: NNNN nSec
END TEST CASE
TEST CASE: LIFO #3
TEST COVERAGE:
k_lifo_init
k_lifo_get(K_FOREVER)
k_lifo_put
k_lifo_get(K_FOREVER)
k_lifo_put
Starting test. Please wait...
TEST RESULT: SUCCESSFUL
DETAILS: Average time for 1 iteration: NNNN nSec
END TEST CASE
TEST CASE: FIFO #1
TEST COVERAGE:
k_fifo_init
k_fifo_get(K_FOREVER)
k_fifo_put
Starting test. Please wait...
TEST RESULT: SUCCESSFUL
DETAILS: Average time for 1 iteration: NNNN nSec
END TEST CASE
TEST CASE: FIFO #2
TEST COVERAGE:
k_fifo_init
k_fifo_get(K_FOREVER)
k_fifo_get(TICKS_NONE)
k_fifo_put
k_yield
Starting test. Please wait...
TEST RESULT: SUCCESSFUL
DETAILS: Average time for 1 iteration: NNNN nSec
END TEST CASE
TEST CASE: FIFO #3
TEST COVERAGE:
k_fifo_init
k_fifo_get(K_FOREVER)
k_fifo_put
k_fifo_get(K_FOREVER)
k_fifo_put
Starting test. Please wait...
TEST RESULT: SUCCESSFUL
DETAILS: Average time for 1 iteration: NNNN nSec
END TEST CASE
TEST CASE: Stack #1
TEST COVERAGE:
k_stack_init
k_stack_pop(TICKS_UNLIMITED)
k_stack_push
Starting test. Please wait...
TEST RESULT: SUCCESSFUL
DETAILS: Average time for 1 iteration: NNNN nSec
END TEST CASE
TEST CASE: Stack #2
TEST COVERAGE:
k_stack_init
k_stack_pop(TICKS_UNLIMITED)
k_stack_pop
k_stack_push
k_yield
Starting test. Please wait...
TEST RESULT: SUCCESSFUL
DETAILS: Average time for 1 iteration: NNNN nSec
END TEST CASE
TEST CASE: Stack #3
TEST COVERAGE:
k_stack_init
k_stack_pop(TICKS_UNLIMITED)
k_stack_push
k_stack_pop(TICKS_UNLIMITED)
k_stack_push
Starting test. Please wait...
TEST RESULT: SUCCESSFUL
DETAILS: Average time for 1 iteration: NNNN nSec
END TEST CASE
PROJECT EXECUTION SUCCESSFUL
QEMU: Terminated

View file

@ -0,0 +1,7 @@
# all printf, fprintf to stdout go to console
CONFIG_STDOUT_CONSOLE=y
# eliminate timer interrupts during the benchmark
CONFIG_SYS_CLOCK_TICKS_PER_SEC=1
CONFIG_MAIN_STACK_SIZE=16384

View file

@ -0,0 +1,7 @@
ccflags-y = -I${ZEPHYR_BASE}/tests/include
obj-y = lifo.o \
mwfifo.o \
sema.o \
stack.o \
syskernel.o

View file

@ -0,0 +1,262 @@
/* lifo.c */
/*
* Copyright (c) 1997-2010, 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "syskernel.h"
struct k_lifo lifo1;
struct k_lifo lifo2;
static struct k_fifo sync_fifo; /* for synchronization */
/**
*
* @brief Initialize LIFOs for the test
*
* @return N/A
*/
void lifo_test_init(void)
{
k_lifo_init(&lifo1);
k_lifo_init(&lifo2);
}
/**
*
* @brief Lifo test thread
*
* @param par1 Ignored parameter.
* @param par2 Number of test loops.
*
* @return N/A
*/
void lifo_thread1(void *par1, void *par2, void *par3)
{
int i;
int element_a[2];
int element_b[2];
int *pelement;
int num_loops = (int) par2;
ARG_UNUSED(par1);
for (i = 0; i < num_loops / 2; i++) {
pelement = (int *)k_lifo_get(&lifo1,
K_FOREVER);
if (pelement[1] != 2 * i) {
break;
}
element_a[1] = 2 * i;
k_lifo_put(&lifo2, element_a);
pelement = (int *)k_lifo_get(&lifo1,
K_FOREVER);
if (pelement[1] != 2 * i + 1) {
break;
}
element_b[1] = 2 * i + 1;
k_lifo_put(&lifo2, element_b);
}
/* wait till it is safe to end: */
k_fifo_get(&sync_fifo, K_FOREVER);
}
/**
*
* @brief Lifo test thread
*
* @param par1 Address of the counter.
* @param par2 Number of test cycles.
*
* @return N/A
*/
void lifo_thread2(void *par1, void *par2, void *par3)
{
int i;
int element[2];
int *pelement;
int *pcounter = (int *)par1;
int num_loops = (int) par2;
for (i = 0; i < num_loops; i++) {
element[1] = i;
k_lifo_put(&lifo1, element);
pelement = (int *)k_lifo_get(&lifo2,
K_FOREVER);
if (pelement[1] != i) {
break;
}
(*pcounter)++;
}
/* wait till it is safe to end: */
k_fifo_get(&sync_fifo, K_FOREVER);
}
/**
*
* @brief Lifo test thread
*
* @param par1 Address of the counter.
* @param par2 Number of test loops.
*
* @return N/A
*/
void lifo_thread3(void *par1, void *par2, void *par3)
{
int i;
int element[2];
int *pelement;
int *pcounter = (int *)par1;
int num_loops = (int) par2;
for (i = 0; i < num_loops; i++) {
element[1] = i;
k_lifo_put(&lifo1, element);
while ((pelement = k_lifo_get(&lifo2,
K_NO_WAIT)) == NULL) {
k_yield();
}
if (pelement[1] != i) {
break;
}
(*pcounter)++;
}
/* wait till it is safe to end: */
k_fifo_get(&sync_fifo, K_FOREVER);
}
/**
*
* @brief The main test entry
*
* @return 1 if success and 0 on failure
*/
int lifo_test(void)
{
uint32_t t;
int i = 0;
int return_value = 0;
int element[2];
int j;
k_fifo_init(&sync_fifo);
/* test get/wait & put thread functions between co-op threads */
fprintf(output_file, sz_test_case_fmt,
"LIFO #1");
fprintf(output_file, sz_description,
"\n\tk_lifo_init"
"\n\tk_lifo_get(K_FOREVER)"
"\n\tk_lifo_put");
printf(sz_test_start_fmt);
lifo_test_init();
t = BENCH_START();
k_thread_spawn(thread_stack1, STACK_SIZE, lifo_thread1,
NULL, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
k_thread_spawn(thread_stack2, STACK_SIZE, lifo_thread2,
(void *) &i, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
t = TIME_STAMP_DELTA_GET(t);
return_value += check_result(i, t);
/* threads have done their job, they can stop now safely: */
for (j = 0; j < 2; j++) {
k_fifo_put(&sync_fifo, (void *) element);
}
/* test get/yield & put thread functions between co-op threads */
fprintf(output_file, sz_test_case_fmt,
"LIFO #2");
fprintf(output_file, sz_description,
"\n\tk_lifo_init"
"\n\tk_lifo_get(K_FOREVER)"
"\n\tk_lifo_get(TICKS_NONE)"
"\n\tk_lifo_put"
"\n\tk_yield");
printf(sz_test_start_fmt);
lifo_test_init();
t = BENCH_START();
i = 0;
k_thread_spawn(thread_stack1, STACK_SIZE, lifo_thread1,
NULL, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
k_thread_spawn(thread_stack2, STACK_SIZE, lifo_thread3,
(void *) &i, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
t = TIME_STAMP_DELTA_GET(t);
return_value += check_result(i, t);
/* threads have done their job, they can stop now safely: */
for (j = 0; j < 2; j++) {
k_fifo_put(&sync_fifo, (void *) element);
}
/* test get wait & put functions between co-op and premptive threads */
fprintf(output_file, sz_test_case_fmt,
"LIFO #3");
fprintf(output_file, sz_description,
"\n\tk_lifo_init"
"\n\tk_lifo_get(K_FOREVER)"
"\n\tk_lifo_put"
"\n\tk_lifo_get(K_FOREVER)"
"\n\tk_lifo_put");
printf(sz_test_start_fmt);
lifo_test_init();
t = BENCH_START();
k_thread_spawn(thread_stack1, STACK_SIZE, lifo_thread1,
NULL, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
for (i = 0; i < NUMBER_OF_LOOPS / 2; i++) {
int element[2];
int *pelement;
element[1] = 2 * i;
k_lifo_put(&lifo1, element);
element[1] = 2 * i + 1;
k_lifo_put(&lifo1, element);
pelement = (int *)k_lifo_get(&lifo2,
K_FOREVER);
if (pelement[1] != 2 * i + 1) {
break;
}
pelement = (int *)k_lifo_get(&lifo2,
K_FOREVER);
if (pelement[1] != 2 * i) {
break;
}
}
t = TIME_STAMP_DELTA_GET(t);
return_value += check_result(i * 2, t);
/* threads have done their job, they can stop now safely: */
for (j = 0; j < 2; j++) {
k_fifo_put(&sync_fifo, (void *) element);
}
return return_value;
}

View file

@ -0,0 +1,261 @@
/* fifo.c */
/*
* Copyright (c) 1997-2010, 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#include "syskernel.h"
struct k_fifo fifo1;
struct k_fifo fifo2;
static struct k_fifo sync_fifo; /* for synchronization */
/**
*
* @brief Initialize FIFOs for the test
*
* @return N/A
*/
void fifo_test_init(void)
{
k_fifo_init(&fifo1);
k_fifo_init(&fifo2);
}
/**
*
* @brief Fifo test thread
*
* @param par1 Ignored parameter.
* @param par2 Number of test loops.
*
* @return N/A
*/
void fifo_thread1(void *par1, void *par2, void *par3)
{
int i;
int element[2];
int *pelement;
int num_loops = (int) par2;
ARG_UNUSED(par1);
ARG_UNUSED(par3);
for (i = 0; i < num_loops; i++) {
pelement = (int *)k_fifo_get(&fifo1,
K_FOREVER);
if (pelement[1] != i) {
break;
}
element[1] = i;
k_fifo_put(&fifo2, element);
}
/* wait till it is safe to end: */
k_fifo_get(&sync_fifo, K_FOREVER);
}
/**
*
* @brief Fifo test thread
*
* @param par1 Address of the counter.
* @param par2 Number of test cycles.
*
* @return N/A
*/
void fifo_thread2(void *par1, void *par2, void *par3)
{
int i;
int element[2];
int *pelement;
int *pcounter = (int *) par1;
int num_loops = (int) par2;
ARG_UNUSED(par3);
for (i = 0; i < num_loops; i++) {
element[1] = i;
k_fifo_put(&fifo1, element);
pelement = (int *)k_fifo_get(&fifo2,
K_FOREVER);
if (pelement[1] != i) {
break;
}
(*pcounter)++;
}
/* wait till it is safe to end: */
k_fifo_get(&sync_fifo, K_FOREVER);
}
/**
*
* @brief Fifo test thread
*
* @param par1 Address of the counter.
* @param par2 Number of test cycles.
*
* @return N/A
*/
void fifo_thread3(void *par1, void *par2, void *par3)
{
int i;
int element[2];
int *pelement;
int *pcounter = (int *)par1;
int num_loops = (int) par2;
ARG_UNUSED(par3);
for (i = 0; i < num_loops; i++) {
element[1] = i;
k_fifo_put(&fifo1, element);
while ((pelement = k_fifo_get(&fifo2,
K_NO_WAIT)) == NULL) {
k_yield();
}
if (pelement[1] != i) {
break;
}
(*pcounter)++;
}
/* wait till it is safe to end: */
k_fifo_get(&sync_fifo, K_FOREVER);
}
/**
*
* @brief The main test entry
*
* @return 1 if success and 0 on failure
*/
int fifo_test(void)
{
uint32_t t;
int i = 0;
int return_value = 0;
int element[2];
int j;
k_fifo_init(&sync_fifo);
/* test get wait & put thread functions between co-op threads */
fprintf(output_file, sz_test_case_fmt,
"FIFO #1");
fprintf(output_file, sz_description,
"\n\tk_fifo_init"
"\n\tk_fifo_get(K_FOREVER)"
"\n\tk_fifo_put");
printf(sz_test_start_fmt);
fifo_test_init();
t = BENCH_START();
k_thread_spawn(thread_stack1, STACK_SIZE, fifo_thread1,
NULL, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
k_thread_spawn(thread_stack2, STACK_SIZE, fifo_thread2,
(void *) &i, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
t = TIME_STAMP_DELTA_GET(t);
return_value += check_result(i, t);
/* threads have done their job, they can stop now safely: */
for (j = 0; j < 2; j++) {
k_fifo_put(&sync_fifo, (void *) element);
}
/* test get/yield & put thread functions between co-op threads */
fprintf(output_file, sz_test_case_fmt,
"FIFO #2");
fprintf(output_file, sz_description,
"\n\tk_fifo_init"
"\n\tk_fifo_get(K_FOREVER)"
"\n\tk_fifo_get(TICKS_NONE)"
"\n\tk_fifo_put"
"\n\tk_yield");
printf(sz_test_start_fmt);
fifo_test_init();
t = BENCH_START();
i = 0;
k_thread_spawn(thread_stack1, STACK_SIZE, fifo_thread1,
NULL, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
k_thread_spawn(thread_stack2, STACK_SIZE, fifo_thread3,
(void *) &i, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
t = TIME_STAMP_DELTA_GET(t);
return_value += check_result(i, t);
/* threads have done their job, they can stop now safely: */
for (j = 0; j < 2; j++) {
k_fifo_put(&sync_fifo, (void *) element);
}
/* test get wait & put functions between co-op and premptive threads */
fprintf(output_file, sz_test_case_fmt,
"FIFO #3");
fprintf(output_file, sz_description,
"\n\tk_fifo_init"
"\n\tk_fifo_get(K_FOREVER)"
"\n\tk_fifo_put"
"\n\tk_fifo_get(K_FOREVER)"
"\n\tk_fifo_put");
printf(sz_test_start_fmt);
fifo_test_init();
t = BENCH_START();
k_thread_spawn(thread_stack1, STACK_SIZE, fifo_thread1,
NULL, (void *) (NUMBER_OF_LOOPS / 2), NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
k_thread_spawn(thread_stack2, STACK_SIZE, fifo_thread1,
NULL, (void *) (NUMBER_OF_LOOPS / 2), NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
for (i = 0; i < NUMBER_OF_LOOPS / 2; i++) {
int element[2];
int *pelement;
element[1] = i;
k_fifo_put(&fifo1, element);
element[1] = i;
k_fifo_put(&fifo1, element);
pelement = (int *)k_fifo_get(&fifo2,
K_FOREVER);
if (pelement[1] != i) {
break;
}
pelement = (int *)k_fifo_get(&fifo2,
K_FOREVER);
if (pelement[1] != i) {
break;
}
}
t = TIME_STAMP_DELTA_GET(t);
return_value += check_result(i * 2, t);
/* threads have done their job, they can stop now safely: */
for (j = 0; j < 2; j++) {
k_fifo_put(&sync_fifo, (void *) element);
}
return return_value;
}

View file

@ -0,0 +1,189 @@
/* sema.c */
/*
* Copyright (c) 1997-2010, 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "syskernel.h"
struct k_sem sem1;
struct k_sem sem2;
/**
*
* @brief Initialize semaphores for the test
*
* @return N/A
*/
void sema_test_init(void)
{
k_sem_init(&sem1, 0, 1);
k_sem_init(&sem2, 0, 1);
}
/**
*
* @brief Semaphore test thread
*
* @param par1 Ignored parameter.
* @param par2 Number of test loops.
*
* @return N/A
*/
void sema_thread1(void *par1, void *par2, void *par3)
{
int i;
int num_loops = (int) par2;
ARG_UNUSED(par1);
ARG_UNUSED(par3);
for (i = 0; i < num_loops; i++) {
k_sem_take(&sem1, K_FOREVER);
k_sem_give(&sem2);
}
}
/**
*
* @brief Semaphore test thread
*
* @param par1 Address of the counter.
* @param par2 Number of test cycles.
*
* @return N/A
*/
void sema_thread2(void *par1, void *par2, void *par3)
{
int i;
int *pcounter = (int *)par1;
int num_loops = (int) par2;
ARG_UNUSED(par3);
for (i = 0; i < num_loops; i++) {
k_sem_give(&sem1);
k_sem_take(&sem2, K_FOREVER);
(*pcounter)++;
}
}
/**
*
* @brief Semaphore test thread
*
* @param par1 Address of the counter.
* @param par2 Number of test cycles.
*
* @return N/A
*/
void sema_thread3(void *par1, void *par2, void *par3)
{
int i;
int *pcounter = (int *)par1;
int num_loops = (int) par2;
ARG_UNUSED(par3);
for (i = 0; i < num_loops; i++) {
k_sem_give(&sem1);
while (k_sem_take(&sem2, K_NO_WAIT) != 0) {
k_yield();
}
(*pcounter)++;
}
}
/**
*
* @brief The main test entry
*
* @return 1 if success and 0 on failure
*/
int sema_test(void)
{
uint32_t t;
int i = 0;
int return_value = 0;
fprintf(output_file, sz_test_case_fmt,
"Semaphore #1");
fprintf(output_file, sz_description,
"\n\tk_sem_init"
"\n\tk_sem_take(TICKS_UNLIMITED)"
"\n\tk_sem_give");
printf(sz_test_start_fmt);
sema_test_init();
t = BENCH_START();
k_thread_spawn(thread_stack1, STACK_SIZE, sema_thread1,
NULL, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
k_thread_spawn(thread_stack2, STACK_SIZE, sema_thread2,
(void *) &i, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
t = TIME_STAMP_DELTA_GET(t);
return_value += check_result(i, t);
fprintf(output_file, sz_test_case_fmt,
"Semaphore #2");
fprintf(output_file, sz_description,
"\n\tk_sem_init"
"\n\tk_sem_take(TICKS_NONE)"
"\n\tk_yield"
"\n\tk_sem_give");
printf(sz_test_start_fmt);
sema_test_init();
i = 0;
t = BENCH_START();
k_thread_spawn(thread_stack1, STACK_SIZE, sema_thread1,
NULL, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
k_thread_spawn(thread_stack2, STACK_SIZE, sema_thread3,
(void *) &i, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
t = TIME_STAMP_DELTA_GET(t);
return_value += check_result(i, t);
fprintf(output_file, sz_test_case_fmt,
"Semaphore #3");
fprintf(output_file, sz_description,
"\n\tk_sem_init"
"\n\tk_sem_take(TICKS_UNLIMITED)"
"\n\tk_sem_give"
"\n\tk_sem_give"
"\n\tk_sem_take(TICKS_UNLIMITED)");
printf(sz_test_start_fmt);
sema_test_init();
t = BENCH_START();
k_thread_spawn(thread_stack1, STACK_SIZE, sema_thread1,
NULL, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
for (i = 0; i < NUMBER_OF_LOOPS; i++) {
k_sem_give(&sem1);
k_sem_take(&sem2, K_FOREVER);
}
t = TIME_STAMP_DELTA_GET(t);
return_value += check_result(i, t);
return return_value;
}

View file

@ -0,0 +1,242 @@
/* stack.c */
/*
* Copyright (c) 1997-2010, 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "syskernel.h"
struct k_stack stack_1;
struct k_stack stack_2;
uint32_t stack1[2];
uint32_t stack2[2];
/**
*
* @brief Initialize stacks for the test
*
* @return N/A
*
*/
void stack_test_init(void)
{
k_stack_init(&stack_1, stack1, 2);
k_stack_init(&stack_2, stack2, 2);
}
/**
*
* @brief Stack test thread
*
* @param par1 Ignored parameter.
* @param par2 Number of test loops.
*
* @return N/A
*
*/
void stack_thread1(void *par1, void *par2, void *par3)
{
int num_loops = ((int) par2 / 2);
int i;
uint32_t data;
ARG_UNUSED(par1);
ARG_UNUSED(par3);
for (i = 0; i < num_loops; i++) {
k_stack_pop(&stack_1, &data, K_FOREVER);
if (data != 2 * i) {
break;
}
data = 2 * i;
k_stack_push(&stack_2, data);
k_stack_pop(&stack_1, &data, K_FOREVER);
if (data != 2 * i + 1) {
break;
}
data = 2 * i + 1;
k_stack_push(&stack_2, data);
}
}
/**
*
* @brief Stack test thread
*
* @param par1 Address of the counter.
* @param par2 Number of test cycles.
*
* @return N/A
*
*/
void stack_thread2(void *par1, void *par2, void *par3)
{
int i;
uint32_t data;
int *pcounter = (int *)par1;
int num_loops = (int) par2;
ARG_UNUSED(par3);
for (i = 0; i < num_loops; i++) {
data = i;
k_stack_push(&stack_1, data);
k_stack_pop(&stack_2, &data, K_FOREVER);
if (data != i) {
break;
}
(*pcounter)++;
}
}
/**
*
* @brief Stack test thread
*
* @param par1 Address of the counter.
* @param par2 Number of test cycles.
*
* @return N/A
*
*/
void stack_thread3(void *par1, void *par2, void *par3)
{
int i;
uint32_t data;
int *pcounter = (int *)par1;
int num_loops = (int) par2;
ARG_UNUSED(par3);
for (i = 0; i < num_loops; i++) {
data = i;
k_stack_push(&stack_1, data);
data = 0xffffffff;
while (k_stack_pop(&stack_2, &data,
K_NO_WAIT) != 0) {
k_yield();
}
if (data != i) {
break;
}
(*pcounter)++;
}
}
/**
*
* @brief The main test entry
*
* @return 1 if success and 0 on failure
*
*/
int stack_test(void)
{
uint32_t t;
int i = 0;
int return_value = 0;
/* test get wait & put stack functions between co-op threads */
fprintf(output_file, sz_test_case_fmt,
"Stack #1");
fprintf(output_file, sz_description,
"\n\tk_stack_init"
"\n\tk_stack_pop(TICKS_UNLIMITED)"
"\n\tk_stack_push");
printf(sz_test_start_fmt);
stack_test_init();
t = BENCH_START();
k_thread_spawn(thread_stack1, STACK_SIZE, stack_thread1,
0, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
k_thread_spawn(thread_stack2, STACK_SIZE, stack_thread2,
(void *) &i, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
t = TIME_STAMP_DELTA_GET(t);
return_value += check_result(i, t);
/* test get/yield & put stack functions between co-op threads */
fprintf(output_file, sz_test_case_fmt,
"Stack #2");
fprintf(output_file, sz_description,
"\n\tk_stack_init"
"\n\tk_stack_pop(TICKS_UNLIMITED)"
"\n\tk_stack_pop"
"\n\tk_stack_push"
"\n\tk_yield");
printf(sz_test_start_fmt);
stack_test_init();
t = BENCH_START();
i = 0;
k_thread_spawn(thread_stack1, STACK_SIZE, stack_thread1,
0, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
k_thread_spawn(thread_stack2, STACK_SIZE, stack_thread3,
(void *) &i, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
t = TIME_STAMP_DELTA_GET(t);
return_value += check_result(i, t);
/* test get wait & put stack functions across co-op and premptive
* threads
*/
fprintf(output_file, sz_test_case_fmt,
"Stack #3");
fprintf(output_file, sz_description,
"\n\tk_stack_init"
"\n\tk_stack_pop(TICKS_UNLIMITED)"
"\n\tk_stack_push"
"\n\tk_stack_pop(TICKS_UNLIMITED)"
"\n\tk_stack_push");
printf(sz_test_start_fmt);
stack_test_init();
t = BENCH_START();
k_thread_spawn(thread_stack1, STACK_SIZE, stack_thread1,
0, (void *) NUMBER_OF_LOOPS, NULL,
K_PRIO_COOP(3), 0, K_NO_WAIT);
for (i = 0; i < NUMBER_OF_LOOPS / 2; i++) {
uint32_t data;
data = 2 * i;
k_stack_push(&stack_1, data);
data = 2 * i + 1;
k_stack_push(&stack_1, data);
k_stack_pop(&stack_2, &data, K_FOREVER);
if (data != 2 * i + 1) {
break;
}
k_stack_pop(&stack_2, &data, K_FOREVER);
if (data != 2 * i) {
break;
}
}
t = TIME_STAMP_DELTA_GET(t);
return_value += check_result(i * 2, t);
return return_value;
}

View file

@ -0,0 +1,192 @@
/* syskernel.c */
/*
* Copyright (c) 1997-2010, 2012-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <tc_util.h>
#include "syskernel.h"
#include <string.h>
char __stack thread_stack1[STACK_SIZE];
char __stack thread_stack2[STACK_SIZE];
char Msg[256];
FILE *output_file;
const char sz_success[] = "SUCCESSFUL";
const char sz_partial[] = "PARTIAL";
const char sz_fail[] = "FAILED";
const char sz_module_title_fmt[] = "\nMODULE: %s";
const char sz_module_result_fmt[] = "\n\nPROJECT EXECUTION %s\n";
const char sz_module_end_fmt[] = "\nEND MODULE";
const char sz_date_fmt[] = "\nBUILD_DATE: %s %s";
const char sz_kernel_ver_fmt[] = "\nKERNEL VERSION: 0x%x";
const char sz_description[] = "\nTEST COVERAGE: %s";
const char sz_test_case_fmt[] = "\n\nTEST CASE: %s";
const char sz_test_start_fmt[] = "\nStarting test. Please wait...";
const char sz_case_result_fmt[] = "\nTEST RESULT: %s";
const char sz_case_details_fmt[] = "\nDETAILS: %s";
const char sz_case_end_fmt[] = "\nEND TEST CASE";
const char sz_case_timing_fmt[] = "%ld nSec";
/* time necessary to read the time */
uint32_t tm_off;
/**
*
* @brief Get the time ticks before test starts
*
* Routine does necessary preparations for the test to start
*
* @return N/A
*/
void begin_test(void)
{
/*
* Invoke bench_test_start in order to be able to use
* tCheck static variable.
*/
bench_test_start();
}
/**
*
* @brief Checks number of tests and calculate average time
*
* @return 1 if success and 0 on failure
*
* @param i Number of tests.
* @param t Time in ticks for the whole test.
*/
int check_result(int i, uint32_t t)
{
/*
* bench_test_end checks tCheck static variable.
* bench_test_start modifies it
*/
if (bench_test_end() != 0) {
fprintf(output_file, sz_case_result_fmt, sz_fail);
fprintf(output_file, sz_case_details_fmt,
"timer tick happened. Results are inaccurate");
fprintf(output_file, sz_case_end_fmt);
return 0;
}
if (i != NUMBER_OF_LOOPS) {
fprintf(output_file, sz_case_result_fmt, sz_fail);
fprintf(output_file, sz_case_details_fmt, "loop counter = ");
fprintf(output_file, "%i !!!", i);
fprintf(output_file, sz_case_end_fmt);
return 0;
}
fprintf(output_file, sz_case_result_fmt, sz_success);
fprintf(output_file, sz_case_details_fmt,
"Average time for 1 iteration: ");
fprintf(output_file, sz_case_timing_fmt,
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(t, NUMBER_OF_LOOPS));
fprintf(output_file, sz_case_end_fmt);
return 1;
}
/**
*
* @brief Check for a key press
*
* @return 1 when a keyboard key is pressed, or 0 if no keyboard support
*/
int kbhit(void)
{
return 0;
}
/**
*
* @brief Prepares the test output
*
* @param continuously Run test till the user presses the key.
*
* @return N/A
*/
void init_output(int *continuously)
{
ARG_UNUSED(continuously);
/*
* send all printf and fprintf to console
*/
output_file = stdout;
}
/**
*
* @brief Close output for the test
*
* @return N/A
*/
void output_close(void)
{
}
/**
*
* @brief Perform all selected benchmarks
*
* @return N/A
*/
void main(void)
{
int continuously = 0;
int test_result;
init_output(&continuously);
bench_test_init();
do {
fprintf(output_file, sz_module_title_fmt,
"kernel API test");
fprintf(output_file, sz_kernel_ver_fmt,
sys_kernel_version_get());
fprintf(output_file,
"\n\nEach test below is repeated %d times;\n"
"average time for one iteration is displayed.",
NUMBER_OF_LOOPS);
test_result = 0;
test_result += sema_test();
test_result += lifo_test();
test_result += fifo_test();
test_result += stack_test();
if (test_result) {
/* sema/lifo/fifo/stack account for 12 tests in total */
if (test_result == 12) {
fprintf(output_file, sz_module_result_fmt,
sz_success);
} else {
fprintf(output_file, sz_module_result_fmt,
sz_partial);
}
} else {
fprintf(output_file, sz_module_result_fmt, sz_fail);
}
TC_PRINT_RUNID;
} while (continuously && !kbhit());
output_close();
}

View file

@ -0,0 +1,61 @@
/* syskernel.h */
/*
* Copyright (c) 1997-2010, 2014 Wind River Systems, Inc.
*
*SPDX-License-Identifier: Apache-2.0
*/
#ifndef SYSKERNEK_H
#define SYSKERNEK_H
#include <timestamp.h>
#include <stdio.h>
#include <toolchain.h>
#define STACK_SIZE 2048
#define NUMBER_OF_LOOPS 5000
extern char thread_stack1[STACK_SIZE];
extern char thread_stack2[STACK_SIZE];
extern FILE *output_file;
extern const char sz_success[];
extern const char sz_partial[];
extern const char sz_fail[];
extern const char sz_module_title_fmt[];
extern const char sz_module_result_fmt[];
extern const char sz_module_end_fmt[];
extern const char sz_product_fmt[];
extern const char sz_kernel_ver_fmt[];
extern const char sz_description[];
extern const char sz_test_case_fmt[];
extern const char sz_test_start_fmt[];
extern const char sz_case_result_fmt[];
extern const char sz_case_details_fmt[];
extern const char sz_case_end_fmt[];
extern const char sz_case_timing_fmt[];
int check_result(int i, uint32_t ticks);
int sema_test(void);
int lifo_test(void);
int fifo_test(void);
int stack_test(void);
void begin_test(void);
static inline uint32_t BENCH_START(void)
{
uint32_t et;
begin_test();
et = TIME_STAMP_DELTA_GET(0);
return et;
}
#endif /* SYSKERNEK_H */

View file

@ -0,0 +1,6 @@
[test]
tags = benchmark
arch_whitelist = x86
filter = not ((CONFIG_DEBUG or CONFIG_ASSERT)) and ( CONFIG_SRAM_SIZE >= 32
or CONFIG_DCCM_SIZE >= 32 or CONFIG_RAM_SIZE >= 32)