| /* 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 |
| * |
| */ |
| 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. |
| * @param par3 unused |
| * |
| */ |
| void fifo_thread1(void *par1, void *par2, void *par3) |
| { |
| int i; |
| intptr_t element[2]; |
| intptr_t *pelement; |
| int num_loops = POINTER_TO_INT(par2); |
| |
| ARG_UNUSED(par1); |
| ARG_UNUSED(par3); |
| for (i = 0; i < num_loops; i++) { |
| pelement = 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. |
| * @param par3 unused |
| * |
| */ |
| void fifo_thread2(void *par1, void *par2, void *par3) |
| { |
| int i; |
| intptr_t element[2]; |
| intptr_t *pelement; |
| int *pcounter = par1; |
| int num_loops = POINTER_TO_INT(par2); |
| |
| ARG_UNUSED(par3); |
| |
| for (i = 0; i < num_loops; i++) { |
| element[1] = i; |
| k_fifo_put(&fifo1, element); |
| pelement = 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. |
| * @param par3 unused |
| * |
| */ |
| void fifo_thread3(void *par1, void *par2, void *par3) |
| { |
| int i; |
| intptr_t element[2]; |
| intptr_t *pelement; |
| int *pcounter = par1; |
| int num_loops = POINTER_TO_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; |
| intptr_t 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_create(&thread_data1, thread_stack1, STACK_SIZE, fifo_thread1, |
| NULL, INT_TO_POINTER(number_of_loops), NULL, |
| K_PRIO_COOP(3), 0, K_NO_WAIT); |
| k_thread_create(&thread_data2, thread_stack2, STACK_SIZE, fifo_thread2, |
| &i, INT_TO_POINTER(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, 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_create(&thread_data1, thread_stack1, STACK_SIZE, fifo_thread1, |
| NULL, INT_TO_POINTER(number_of_loops), NULL, |
| K_PRIO_COOP(3), 0, K_NO_WAIT); |
| k_thread_create(&thread_data2, thread_stack2, STACK_SIZE, fifo_thread3, |
| &i, INT_TO_POINTER(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, element); |
| } |
| |
| /* test get wait & put functions between co-op and preemptive 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_create(&thread_data1, thread_stack1, STACK_SIZE, fifo_thread1, |
| NULL, INT_TO_POINTER(number_of_loops / 2U), NULL, |
| K_PRIO_COOP(3), 0, K_NO_WAIT); |
| k_thread_create(&thread_data2, thread_stack2, STACK_SIZE, fifo_thread1, |
| NULL, INT_TO_POINTER(number_of_loops / 2U), NULL, |
| K_PRIO_COOP(3), 0, K_NO_WAIT); |
| for (i = 0; i < number_of_loops / 2U; i++) { |
| intptr_t element[2]; |
| intptr_t *pelement; |
| |
| element[1] = i; |
| k_fifo_put(&fifo1, element); |
| element[1] = i; |
| k_fifo_put(&fifo1, element); |
| |
| pelement = k_fifo_get(&fifo2, K_FOREVER); |
| if (pelement[1] != i) { |
| break; |
| } |
| pelement = 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, element); |
| } |
| |
| return return_value; |
| } |