/* 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;
}
