diff options
Diffstat (limited to 'tests/benchmark/sys_kernel/src/mwfifo.c')
-rw-r--r-- | tests/benchmark/sys_kernel/src/mwfifo.c | 261 |
1 files changed, 261 insertions, 0 deletions
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; +} |