blob: 0318f4d157dcb2116fc8ec0489dc55a3a34f462b [file] [log] [blame]
/* 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;
}