summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/benchmark/sys_kernel/Makefile4
-rw-r--r--tests/benchmark/sys_kernel/README.txt177
-rw-r--r--tests/benchmark/sys_kernel/prj.conf7
-rw-r--r--tests/benchmark/sys_kernel/src/Makefile7
-rw-r--r--tests/benchmark/sys_kernel/src/lifo.c262
-rw-r--r--tests/benchmark/sys_kernel/src/mwfifo.c261
-rw-r--r--tests/benchmark/sys_kernel/src/sema.c189
-rw-r--r--tests/benchmark/sys_kernel/src/stack.c242
-rw-r--r--tests/benchmark/sys_kernel/src/syskernel.c192
-rw-r--r--tests/benchmark/sys_kernel/src/syskernel.h61
-rw-r--r--tests/benchmark/sys_kernel/testcase.ini6
11 files changed, 1408 insertions, 0 deletions
diff --git a/tests/benchmark/sys_kernel/Makefile b/tests/benchmark/sys_kernel/Makefile
new file mode 100644
index 000000000..e70a750a8
--- /dev/null
+++ b/tests/benchmark/sys_kernel/Makefile
@@ -0,0 +1,4 @@
+BOARD ?= qemu_x86
+CONF_FILE = prj.conf
+
+include ${ZEPHYR_BASE}/Makefile.test
diff --git a/tests/benchmark/sys_kernel/README.txt b/tests/benchmark/sys_kernel/README.txt
new file mode 100644
index 000000000..269d2effb
--- /dev/null
+++ b/tests/benchmark/sys_kernel/README.txt
@@ -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
+
diff --git a/tests/benchmark/sys_kernel/prj.conf b/tests/benchmark/sys_kernel/prj.conf
new file mode 100644
index 000000000..701871dc9
--- /dev/null
+++ b/tests/benchmark/sys_kernel/prj.conf
@@ -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
diff --git a/tests/benchmark/sys_kernel/src/Makefile b/tests/benchmark/sys_kernel/src/Makefile
new file mode 100644
index 000000000..842415603
--- /dev/null
+++ b/tests/benchmark/sys_kernel/src/Makefile
@@ -0,0 +1,7 @@
+ccflags-y = -I${ZEPHYR_BASE}/tests/include
+
+obj-y = lifo.o \
+ mwfifo.o \
+ sema.o \
+ stack.o \
+ syskernel.o
diff --git a/tests/benchmark/sys_kernel/src/lifo.c b/tests/benchmark/sys_kernel/src/lifo.c
new file mode 100644
index 000000000..0a48be22d
--- /dev/null
+++ b/tests/benchmark/sys_kernel/src/lifo.c
@@ -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;
+}
diff --git a/tests/benchmark/sys_kernel/src/mwfifo.c b/tests/benchmark/sys_kernel/src/mwfifo.c
new file mode 100644
index 000000000..cccac0066
--- /dev/null
+++ b/tests/benchmark/sys_kernel/src/mwfifo.c
@@ -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;
+}
diff --git a/tests/benchmark/sys_kernel/src/sema.c b/tests/benchmark/sys_kernel/src/sema.c
new file mode 100644
index 000000000..77d4660d4
--- /dev/null
+++ b/tests/benchmark/sys_kernel/src/sema.c
@@ -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;
+}
diff --git a/tests/benchmark/sys_kernel/src/stack.c b/tests/benchmark/sys_kernel/src/stack.c
new file mode 100644
index 000000000..9ae966621
--- /dev/null
+++ b/tests/benchmark/sys_kernel/src/stack.c
@@ -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;
+}
diff --git a/tests/benchmark/sys_kernel/src/syskernel.c b/tests/benchmark/sys_kernel/src/syskernel.c
new file mode 100644
index 000000000..a29a916c8
--- /dev/null
+++ b/tests/benchmark/sys_kernel/src/syskernel.c
@@ -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();
+}
diff --git a/tests/benchmark/sys_kernel/src/syskernel.h b/tests/benchmark/sys_kernel/src/syskernel.h
new file mode 100644
index 000000000..6bee48c59
--- /dev/null
+++ b/tests/benchmark/sys_kernel/src/syskernel.h
@@ -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 */
diff --git a/tests/benchmark/sys_kernel/testcase.ini b/tests/benchmark/sys_kernel/testcase.ini
new file mode 100644
index 000000000..70b3bd210
--- /dev/null
+++ b/tests/benchmark/sys_kernel/testcase.ini
@@ -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)
+