243 lines
4.5 KiB
C
243 lines
4.5 KiB
C
/* 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;
|
|
|
|
u32_t stack1[2];
|
|
u32_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;
|
|
u32_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;
|
|
u32_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;
|
|
u32_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)
|
|
{
|
|
u32_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, (void *) 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, (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(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, (void *) 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, (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(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, (void *) NUMBER_OF_LOOPS, NULL,
|
|
K_PRIO_COOP(3), 0, K_NO_WAIT);
|
|
|
|
for (i = 0; i < NUMBER_OF_LOOPS / 2; i++) {
|
|
u32_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;
|
|
}
|