/* 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)
{
	u32_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_create(&thread_data1, thread_stack1, STACK_SIZE, fifo_thread1,
			 NULL, (void *) NUMBER_OF_LOOPS, NULL,
			 K_PRIO_COOP(3), 0, K_NO_WAIT);
	k_thread_create(&thread_data2, 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_create(&thread_data1, thread_stack1, STACK_SIZE, fifo_thread1,
			 NULL, (void *) NUMBER_OF_LOOPS, NULL,
			 K_PRIO_COOP(3), 0, K_NO_WAIT);
	k_thread_create(&thread_data2, 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_create(&thread_data1, thread_stack1, STACK_SIZE, fifo_thread1,
			 NULL, (void *) (NUMBER_OF_LOOPS / 2), NULL,
			 K_PRIO_COOP(3), 0, K_NO_WAIT);
	k_thread_create(&thread_data2, 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;
}
