unified/tests: Remove nanokernel test part from latency_measure

Nanokernel part of the latency_measure test is a subset of the
microkekernel tests. For unified kernel there is no reason to
have nanokernel test - for unified kernel we have to run whole
the set of tests.

Change-Id: Ief176fd9d25e7355e3d3697c3bbc1e953b16655c
Signed-off-by: Dmitriy Korovkin <dmitriy.korovkin@windriver.com>
This commit is contained in:
Dmitriy Korovkin 2016-11-01 17:05:18 -04:00 committed by Anas Nashif
parent a037316bb5
commit b4db06615d
26 changed files with 104 additions and 218 deletions

View file

@ -1,5 +1,5 @@
ccflags-y += -I$(CURDIR)/misc/generated/sysgen
ccflags-y += -I$(ZEPHYR_BASE)/tests/legacy/benchmark/latency_measure/microkernel/src \
ccflags-y += -I$(ZEPHYR_BASE)/tests/legacy/benchmark/latency_measure/src \
-I${ZEPHYR_BASE}/tests/include
obj-y := fifo_b.o mailbox_b.o master.o mempool_b.o \

View file

@ -1,6 +0,0 @@
KERNEL_TYPE = nano
BOARD ?= qemu_x86
CONF_FILE = prj.conf
SOURCE_DIR = $(ZEPHYR_BASE)/tests/legacy/benchmark/latency_measure/microkernel/src/
include $(ZEPHYR_BASE)/Makefile.inc

View file

@ -1,62 +0,0 @@
Title: Latency Measurement
Description:
This benchmark measures the latency of selected nanokernel features.
IMPORTANT: The results below were generated using a simulation environment,
and may not reflect the results that will be generated using other
environments (simulated or otherwise).
--------------------------------------------------------------------------------
Building and Running Project:
This nanokernel 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:
|-----------------------------------------------------------------------------|
| Nanokernel Latency Benchmark |
|-----------------------------------------------------------------------------|
| tcs = timer clock cycles: 1 tcs is N nsec |
|-----------------------------------------------------------------------------|
| 1- Measure time to switch from fiber to ISR execution |
| switching time is NNNN tcs = NNNNN nsec |
|-----------------------------------------------------------------------------|
| 2- Measure time to switch from ISR back to interrupted fiber |
| switching time is NNNN tcs = NNNNN nsec |
|-----------------------------------------------------------------------------|
| 3- Measure time from ISR to executing a different fiber (rescheduled) |
| switching time is NNNN tcs = NNNNN nsec |
|-----------------------------------------------------------------------------|
| 4- Measure average context switch time between fibers |
| Average context switch time is NNNN tcs = NNNNN nsec |
|-----------------------------------------------------------------------------|
| 5- Measure average time to lock then unlock interrupts |
| 5.1- When each lock and unlock is executed as a function call |
| Average time for lock then unlock is NNNN tcs = NNNN nsec |
| |
| 5.2- When each lock and unlock is executed as inline function call |
| Average time for lock then unlock is NNN tcs = NNNN nsec |
|-----------------------------------------------------------------------------|
| E N D |
|-----------------------------------------------------------------------------|

View file

@ -1,5 +0,0 @@
# needed for printf output sent to console
CONFIG_STDOUT_CONSOLE=y
# We need this API to run functions in IRQ context
CONFIG_IRQ_OFFLOAD=y

View file

@ -1,4 +0,0 @@
[test]
tags = benchmark
arch_whitelist = x86

View file

@ -28,7 +28,7 @@
#include <arch/cpu.h>
uint32_t tm_off; /* time necessary to read the time */
int errorCount = 0; /* track number of errors */
int errorCount; /* track number of errors */
/**
*
@ -57,25 +57,6 @@ void nanoTest(void)
printDashLine();
}
#ifdef CONFIG_NANOKERNEL
/**
*
* @brief Nanokernel-only testing entry point
*
* @return N/A
*/
void main(void)
{
bench_test_init();
nanoTest();
PRINT_END_BANNER();
TC_END_REPORT(errorCount);
}
#else
int microIntToTaskEvt(void);
int microIntToTask(void);
int microSemaLockUnlock(void);
@ -125,4 +106,3 @@ void microMain(void)
PRINT_END_BANNER();
TC_END_REPORT(errorCount);
}
#endif /* CONFIG_NANOKERNEL */

View file

@ -22,14 +22,13 @@
* handler back to the interrupted task in microkernel.
*/
#ifdef CONFIG_MICROKERNEL
#include "timestamp.h"
#include "utils.h"
#include <arch/cpu.h>
#include <irq_offload.h>
static volatile int flagVar = 0;
static volatile int flagVar;
static uint32_t timestamp;
@ -78,14 +77,12 @@ static void makeInt(void)
int microIntToTask(void)
{
PRINT_FORMAT(" 1- Measure time to switch from ISR back to"
" interrupted task");
" interrupted task");
TICK_SYNCH();
makeInt();
if (flagVar == 1) {
PRINT_FORMAT(" switching time is %lu tcs = %lu nsec",
timestamp, SYS_CLOCK_HW_CYCLES_TO_NS(timestamp));
timestamp, SYS_CLOCK_HW_CYCLES_TO_NS(timestamp));
}
return 0;
}
#endif /* MICROKERNEL */

View file

@ -24,7 +24,6 @@
* interrupted.
*/
#ifdef CONFIG_MICROKERNEL
#include <zephyr.h>
#include <irq_offload.h>
@ -33,7 +32,7 @@
#include <arch/cpu.h>
static uint32_t timestamp = 0;
static uint32_t timestamp;
/**
*
@ -56,8 +55,8 @@ static void latencyTestIsr(void *unused)
* @brief Software interrupt generating task
*
* Lower priority task that, when starts, waits for a semaphore. When gets
* it, released by the main task, sets up the interrupt handler and generates the
* software interrupt
* it, released by the main task, sets up the interrupt handler and generates
* the software interrupt
*
* @return 0 on success
*/
@ -76,15 +75,13 @@ void microInt(void)
*/
int microIntToTaskEvt(void)
{
PRINT_FORMAT(" 2- Measure time from ISR to executing a different task"
" (rescheduled)");
PRINT_FORMAT(" 2 - Measure time from ISR to executing a different task"
" (rescheduled)");
TICK_SYNCH();
task_sem_give(INTSEMA);
task_event_recv(EVENT0, TICKS_UNLIMITED);
timestamp = TIME_STAMP_DELTA_GET(timestamp);
PRINT_FORMAT(" switch time is %lu tcs = %lu nsec",
timestamp, SYS_CLOCK_HW_CYCLES_TO_NS(timestamp));
timestamp, SYS_CLOCK_HW_CYCLES_TO_NS(timestamp));
return 0;
}
#endif /* CONFIG_MICROKERNEL */

View file

@ -23,7 +23,6 @@
* mutex being tested.
*/
#ifdef CONFIG_MICROKERNEL
#include <zephyr.h>
#include "timestamp.h"
@ -53,7 +52,7 @@ int microSemaLockUnlock(void)
int i;
PRINT_FORMAT(" 3- Measure average time to signal a sema then test"
" that sema");
" that sema");
bench_test_start();
timestamp = TIME_STAMP_DELTA_GET(0);
for (i = 0; i < N_TEST_SEMA; i++) {
@ -61,9 +60,11 @@ int microSemaLockUnlock(void)
}
timestamp = TIME_STAMP_DELTA_GET(timestamp);
if (bench_test_end() == 0) {
PRINT_FORMAT(" Average semaphore signal time %lu tcs = %lu nsec",
timestamp / N_TEST_SEMA,
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(timestamp, N_TEST_SEMA));
PRINT_FORMAT(" Average semaphore signal time %lu tcs = %lu"
" nsec",
timestamp / N_TEST_SEMA,
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(timestamp,
N_TEST_SEMA));
} else {
errorCount++;
PRINT_OVERFLOW_ERROR();
@ -76,9 +77,11 @@ int microSemaLockUnlock(void)
}
timestamp = TIME_STAMP_DELTA_GET(timestamp);
if (bench_test_end() == 0) {
PRINT_FORMAT(" Average semaphore test time %lu tcs = %lu nsec",
timestamp / N_TEST_SEMA,
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(timestamp, N_TEST_SEMA));
PRINT_FORMAT(" Average semaphore test time %lu tcs = %lu "
"nsec",
timestamp / N_TEST_SEMA,
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(timestamp,
N_TEST_SEMA));
} else {
errorCount++;
PRINT_OVERFLOW_ERROR();
@ -100,24 +103,22 @@ int microMutexLockUnlock(void)
int i;
PRINT_FORMAT(" 4- Measure average time to lock a mutex then"
" unlock that mutex");
" unlock that mutex");
timestamp = TIME_STAMP_DELTA_GET(0);
for (i = 0; i < N_TEST_MUTEX; i++) {
task_mutex_lock(TEST_MUTEX, TICKS_UNLIMITED);
}
timestamp = TIME_STAMP_DELTA_GET(timestamp);
PRINT_FORMAT(" Average time to lock the mutex %lu tcs = %lu nsec",
timestamp / N_TEST_MUTEX,
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(timestamp, N_TEST_MUTEX));
timestamp / N_TEST_MUTEX,
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(timestamp, N_TEST_MUTEX));
timestamp = TIME_STAMP_DELTA_GET(0);
for (i = 0; i <= N_TEST_MUTEX; i++) {
task_mutex_unlock(TEST_MUTEX);
}
timestamp = TIME_STAMP_DELTA_GET(timestamp);
PRINT_FORMAT(" Average time to unlock the mutex %lu tcs = %lu nsec",
timestamp / N_TEST_MUTEX,
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(timestamp, N_TEST_MUTEX));
timestamp / N_TEST_MUTEX,
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(timestamp, N_TEST_MUTEX));
return 0;
}
#endif /* CONFIG_MICROKERNEL */

View file

@ -23,7 +23,6 @@
* context switch.
*/
#ifdef CONFIG_MICROKERNEL
#include <zephyr.h>
#include "timestamp.h" /* reading time */
#include "utils.h" /* PRINT () and other macros */
@ -34,7 +33,7 @@ static int abs(int i) { return (i >= 0) ? i : -i; }
/* context switch enough time so our measurement is precise */
#define NB_OF_YIELD 1000
static uint32_t helper_task_iterations = 0;
static uint32_t helper_task_iterations;
/**
*
@ -64,8 +63,8 @@ void microTaskSwitchYield(void)
int32_t delta;
uint32_t timestamp;
PRINT_FORMAT(" 5- Measure average context switch time between tasks using"
" (task_yield)");
PRINT_FORMAT(" 5- Measure average context switch time between tasks"
" using (task_yield)");
bench_test_start();
@ -76,7 +75,8 @@ void microTaskSwitchYield(void)
timestamp = TIME_STAMP_DELTA_GET(0);
/* loop until either helper or this routine reaches number of yields */
while (iterations < NB_OF_YIELD && helper_task_iterations < NB_OF_YIELD) {
while (iterations < NB_OF_YIELD &&
helper_task_iterations < NB_OF_YIELD) {
task_yield();
iterations++;
}
@ -84,11 +84,12 @@ void microTaskSwitchYield(void)
/* get the number of cycles it took to do the test */
timestamp = TIME_STAMP_DELTA_GET(timestamp);
/* Ensure both helper and this routine were context switching back & forth.
/* Ensure both helper and this routine were context switching back &
* forth.
* For execution to reach the line below, either this routine or helper
* routine reached NB_OF_YIELD. The other loop must be at most one
* iteration away from reaching NB_OF_YIELD if execute was switching back
* and forth.
* iteration away from reaching NB_OF_YIELD if execute was switching
* back and forth.
*/
delta = iterations - helper_task_iterations;
if (bench_test_end() < 0) {
@ -100,17 +101,15 @@ void microTaskSwitchYield(void)
*/
errorCount++;
PRINT_FORMAT(" Error, iteration:%lu, helper iteration:%lu",
iterations, helper_task_iterations);
iterations, helper_task_iterations);
} else {
/* task_yield is called (iterations + helper_task_iterations)
* times in total.
*/
PRINT_FORMAT(" Average task context switch using "
"yield %lu tcs = %lu nsec",
timestamp / (iterations + helper_task_iterations),
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(timestamp,
(iterations + helper_task_iterations)));
"yield %lu tcs = %lu nsec",
timestamp / (iterations + helper_task_iterations),
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(timestamp,
(iterations + helper_task_iterations)));
}
}
#endif

View file

@ -44,13 +44,13 @@ static char __stack fiberTwoStack[STACKSIZE];
/* semaphore used for fibers synchronization */
static struct nano_sem syncSema;
static uint32_t timestamp = 0;
static uint32_t timestamp;
/* context switches counter */
static volatile uint32_t ctxSwitchCounter = 0;
static volatile uint32_t ctxSwitchCounter;
/* context switch balancer. Incremented by one fiber, decremented by another*/
static volatile int ctxSwitchBalancer = 0;
static volatile int ctxSwitchBalancer;
/**
*
@ -107,18 +107,20 @@ int nanoCtxSwitch(void)
bench_test_start();
task_fiber_start(&fiberOneStack[0], STACKSIZE,
(nano_fiber_entry_t) fiberOne, 0, 0, 6, 0);
(nano_fiber_entry_t) fiberOne, 0, 0, 6, 0);
task_fiber_start(&fiberTwoStack[0], STACKSIZE,
(nano_fiber_entry_t) fiberTwo, 0, 0, 6, 0);
(nano_fiber_entry_t) fiberTwo, 0, 0, 6, 0);
if (ctxSwitchBalancer > 3 || ctxSwitchBalancer < -3) {
PRINT_FORMAT(" Balance is %d. FAILED", ctxSwitchBalancer);
} else if (bench_test_end() != 0) {
errorCount++;
PRINT_OVERFLOW_ERROR();
} else {
PRINT_FORMAT(" Average context switch time is %lu tcs = %lu nsec",
timestamp / ctxSwitchCounter,
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(timestamp, ctxSwitchCounter));
PRINT_FORMAT(" Average context switch time is %lu tcs = %lu"
" nsec",
timestamp / ctxSwitchCounter,
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(timestamp,
ctxSwitchCounter));
}
return 0;
}

View file

@ -78,8 +78,8 @@ int nanoIntLatency(void)
PRINT_FORMAT(" 1- Measure time to switch from fiber to ISR execution");
TICK_SYNCH();
task_fiber_start(&fiberStack[0], STACKSIZE,
(nano_fiber_entry_t) fiberInt, 0, 0, 6, 0);
(nano_fiber_entry_t) fiberInt, 0, 0, 6, 0);
PRINT_FORMAT(" switching time is %lu tcs = %lu nsec",
timestamp, SYS_CLOCK_HW_CYCLES_TO_NS(timestamp));
timestamp, SYS_CLOCK_HW_CYCLES_TO_NS(timestamp));
return 0;
}

View file

@ -33,7 +33,7 @@
/* total number of interrupt lock/unlock cycles */
#define NTESTS 100000
static uint32_t timestamp = 0;
static uint32_t timestamp;
/**
*
@ -56,8 +56,9 @@ int nanoIntLockUnlock(void)
timestamp = TIME_STAMP_DELTA_GET(timestamp);
if (bench_test_end() == 0) {
PRINT_FORMAT(" Average time for lock then unlock "
"is %lu tcs = %lu nsec",
timestamp / NTESTS, SYS_CLOCK_HW_CYCLES_TO_NS_AVG(timestamp, NTESTS));
"is %lu tcs = %lu nsec",
timestamp / NTESTS,
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(timestamp, NTESTS));
} else {
errorCount++;
PRINT_OVERFLOW_ERROR();

View file

@ -35,7 +35,7 @@
/* stack used by the fiber that generates the interrupt */
static char __stack fiberStack[STACKSIZE];
static volatile int flagVar = 0;
static volatile int flagVar;
static uint32_t timestamp;
@ -84,13 +84,13 @@ static void fiberInt(void)
int nanoIntToFiber(void)
{
PRINT_FORMAT(" 2- Measure time to switch from ISR back to interrupted"
" fiber");
" fiber");
TICK_SYNCH();
task_fiber_start(&fiberStack[0], STACKSIZE,
(nano_fiber_entry_t) fiberInt, 0, 0, 6, 0);
(nano_fiber_entry_t) fiberInt, 0, 0, 6, 0);
if (flagVar == 1) {
PRINT_FORMAT(" switching time is %lu tcs = %lu nsec",
timestamp, SYS_CLOCK_HW_CYCLES_TO_NS(timestamp));
timestamp, SYS_CLOCK_HW_CYCLES_TO_NS(timestamp));
}
return 0;
}

View file

@ -27,7 +27,7 @@
* interrupt handler releases the semaphore which enabled the high priority
* fiberWaiter to run and exit. The high priority fiber acquire the sema and
* read the time. The time delta is measured from the time
* semaphore is released in interrup handler to the time fiberWaiter
* semaphore is released in interrupt handler to the time fiberWaiter
* starts to executing.
*/
@ -48,7 +48,7 @@ static char __stack intStack[STACKSIZE];
/* semaphore taken by waiting fiber ad released by the interrupt handler */
static struct nano_sem testSema;
static uint32_t timestamp = 0;
static uint32_t timestamp;
/**
*
@ -105,16 +105,16 @@ static void fiberWaiter(void)
int nanoIntToFiberSem(void)
{
PRINT_FORMAT(" 3- Measure time from ISR to executing a different fiber"
" (rescheduled)");
" (rescheduled)");
nano_sem_init(&testSema);
TICK_SYNCH();
task_fiber_start(&waiterStack[0], STACKSIZE,
(nano_fiber_entry_t) fiberWaiter, 0, 0, 5, 0);
(nano_fiber_entry_t) fiberWaiter, 0, 0, 5, 0);
task_fiber_start(&intStack[0], STACKSIZE,
(nano_fiber_entry_t) fiberInt, 0, 0, 6, 0);
(nano_fiber_entry_t) fiberInt, 0, 0, 6, 0);
PRINT_FORMAT(" switching time is %lu tcs = %lu nsec",
timestamp, SYS_CLOCK_HW_CYCLES_TO_NS(timestamp));
timestamp, SYS_CLOCK_HW_CYCLES_TO_NS(timestamp));
return 0;
}

View file

@ -33,30 +33,10 @@
#include <test_asm_inline_other.h>
#endif
#if defined(CONFIG_NANOKERNEL)
/* number of ticks before timer overflows */
#define BENCH_MAX_TICKS (sys_clock_ticks_per_sec - 1)
typedef int64_t TICK_TYPE;
static inline void TICK_SYNCH(void)
{
TICK_TYPE reftime;
(void) sys_tick_delta(&reftime);
while (sys_tick_delta(&reftime) == 0) {
}
}
#elif defined(CONFIG_MICROKERNEL)
typedef int64_t TICK_TYPE;
#define TICK_SYNCH() task_sleep(1)
#else
#error either CONFIG_NANOKERNEL or CONFIG_MICROKERNEL must be defined
#endif /* CONFIG_NANOKERNEL */
#define TICK_GET(x) ((TICK_TYPE) sys_tick_delta(x))
#define OS_GET_TIME() sys_cycle_get_32()
@ -71,7 +51,8 @@ static inline uint32_t TIME_STAMP_DELTA_GET(uint32_t ts)
timestamp_serialize();
t = OS_GET_TIME();
uint32_t res = (t >= ts)? (t - ts): (ULONG_MAX - ts + t);
uint32_t res = (t >= ts) ? (t - ts) : (ULONG_MAX - ts + t);
if (ts > 0) {
res -= tm_off;
}
@ -89,13 +70,9 @@ static inline void bench_test_init(void)
tm_off = OS_GET_TIME() - t;
}
#if defined(CONFIG_MICROKERNEL)
/* number of ticks before timer overflows */
#define BENCH_MAX_TICKS (sys_clock_ticks_per_sec - 1)
#endif /* CONFIG_MICROKERNEL */
/* tickstamp used for timer counter overflow check */
static TICK_TYPE tCheck;

View file

@ -37,10 +37,10 @@ extern int errorCount;
#define PRINT(fmt, ...) printk(fmt, ##__VA_ARGS__)
#define PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
#define PRINT_FORMAT(fmt, ...) \
#define PRINT_FORMAT(fmt, ...) \
do { \
snprintf(tmpString, TMP_STRING_SIZE, fmt, ##__VA_ARGS__); \
PRINTF("|%-77s|\n", tmpString); \
snprintf(tmpString, TMP_STRING_SIZE, fmt, ##__VA_ARGS__); \
PRINTF("|%-77s|\n", tmpString); \
} while (0)
/**
@ -51,33 +51,42 @@ extern int errorCount;
*/
static inline void printDashLine(void)
{
PRINTF("|-----------------------------------------------------------------"
"------------|\n");
PRINTF("|-------------------------------------------------------"
"----------------------|\n");
}
#define PRINT_END_BANNER() \
PRINTF("| E N D "\
" |\n"); \
printDashLine();
#define PRINT_END_BANNER() \
do { \
PRINTF("| E N D " \
" |\n"); \
printDashLine(); \
} while (0)
#define PRINT_NANO_BANNER() \
printDashLine(); \
PRINTF("| Nanokernel Latency Benchmark "\
" |\n"); \
printDashLine();
#define PRINT_NANO_BANNER() \
do { \
printDashLine(); \
PRINTF("| Nanokernel Latency Benchmark " \
" |\n"); \
printDashLine(); \
} while (0)
#define PRINT_MICRO_BANNER() \
printDashLine(); \
PRINTF("| Microkernel Latency Benchmark "\
" |\n"); \
printDashLine();
#define PRINT_MICRO_BANNER() \
do { \
printDashLine(); \
PRINTF("| Microkernel Latency Benchmark " \
" |\n"); \
printDashLine(); \
} while (0)
#define PRINT_TIME_BANNER() \
PRINT_FORMAT(" tcs = timer clock cycles: 1 tcs is %lu nsec", \
SYS_CLOCK_HW_CYCLES_TO_NS(1)); \
printDashLine();
#define PRINT_OVERFLOW_ERROR() \
#define PRINT_TIME_BANNER() \
do { \
PRINT_FORMAT(" tcs = timer clock cycles: 1 tcs is %lu nsec", \
SYS_CLOCK_HW_CYCLES_TO_NS(1)); \
printDashLine(); \
} while (0)
#define PRINT_OVERFLOW_ERROR() \
PRINT_FORMAT(" Error: tick occurred")
#else

View file

@ -1,5 +1,5 @@
[test]
tags = benchmark
tags = benchmark unified_capable
arch_whitelist = x86
kernel = micro

View file

@ -1,4 +1,4 @@
ccflags-y = -I$(ZEPHYR_BASE)/tests/legacy/benchmark/latency_measure/microkernel/src -I${ZEPHYR_BASE}/tests/include
ccflags-y = -I$(ZEPHYR_BASE)/tests/legacy/benchmark/latency_measure/src -I${ZEPHYR_BASE}/tests/include
ccflags-y += -I$(CURDIR)/misc/generated/sysgen
obj-y = lifo.o \