|  | /* 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; | 
|  |  | 
|  | stack_data_t stack1[2]; | 
|  | stack_data_t stack2[2]; | 
|  |  | 
|  | /** | 
|  | * | 
|  | * @brief Initialize stacks for the test | 
|  | * | 
|  | */ | 
|  | 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. | 
|  | * @param par3	 Unused | 
|  | * | 
|  | */ | 
|  | void stack_thread1(void *par1, void *par2, void *par3) | 
|  | { | 
|  | int num_loops = POINTER_TO_INT(par2) / 2; | 
|  | int i; | 
|  | stack_data_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. | 
|  | * @param par3	 Unused | 
|  | * | 
|  | */ | 
|  | void stack_thread2(void *par1, void *par2, void *par3) | 
|  | { | 
|  | int i; | 
|  | stack_data_t data; | 
|  | int *pcounter = par1; | 
|  | int num_loops = POINTER_TO_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. | 
|  | * @param par3	 Unused | 
|  | * | 
|  | */ | 
|  | void stack_thread3(void *par1, void *par2, void *par3) | 
|  | { | 
|  | int i; | 
|  | stack_data_t data; | 
|  | int *pcounter = par1; | 
|  | int num_loops = POINTER_TO_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(K_FOREVER)" | 
|  | "\n\tk_stack_push"); | 
|  | printf(sz_test_start_fmt); | 
|  |  | 
|  | stack_test_init(); | 
|  |  | 
|  | t = BENCH_START(); | 
|  |  | 
|  | k_thread_create(&thread_data1, thread_stack1, STACK_SIZE, stack_thread1, | 
|  | 0, INT_TO_POINTER(number_of_loops), NULL, | 
|  | K_PRIO_COOP(3), 0, K_NO_WAIT); | 
|  | k_thread_create(&thread_data2, thread_stack2, STACK_SIZE, stack_thread2, | 
|  | (void *) &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); | 
|  |  | 
|  | /* 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(K_FOREVER)" | 
|  | "\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_create(&thread_data1, thread_stack1, STACK_SIZE, stack_thread1, | 
|  | 0, INT_TO_POINTER(number_of_loops), NULL, | 
|  | K_PRIO_COOP(3), 0, K_NO_WAIT); | 
|  | k_thread_create(&thread_data2, thread_stack2, STACK_SIZE, stack_thread3, | 
|  | (void *) &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); | 
|  |  | 
|  | /* test get wait & put stack functions across co-op and preemptive | 
|  | * threads | 
|  | */ | 
|  | fprintf(output_file, sz_test_case_fmt, | 
|  | "Stack #3"); | 
|  | fprintf(output_file, sz_description, | 
|  | "\n\tk_stack_init" | 
|  | "\n\tk_stack_pop(K_FOREVER)" | 
|  | "\n\tk_stack_push" | 
|  | "\n\tk_stack_pop(K_FOREVER)" | 
|  | "\n\tk_stack_push"); | 
|  | printf(sz_test_start_fmt); | 
|  |  | 
|  | stack_test_init(); | 
|  |  | 
|  | t = BENCH_START(); | 
|  |  | 
|  | k_thread_create(&thread_data1, thread_stack1, STACK_SIZE, stack_thread1, | 
|  | 0, INT_TO_POINTER(number_of_loops), NULL, | 
|  | K_PRIO_COOP(3), 0, K_NO_WAIT); | 
|  |  | 
|  | for (i = 0; i < number_of_loops / 2U; i++) { | 
|  | stack_data_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; | 
|  | } |