/* lifo.c */

/*
 * Copyright (c) 1997-2010, 2013-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "syskernel.h"

struct k_lifo lifo1;
struct k_lifo lifo2;

static struct k_fifo sync_fifo; /* for synchronization */

/**
 *
 * @brief Initialize LIFOs for the test
 *
 * @return N/A
 */
void lifo_test_init(void)
{
	k_lifo_init(&lifo1);
	k_lifo_init(&lifo2);
}


/**
 *
 * @brief Lifo test thread
 *
 * @param par1   Ignored parameter.
 * @param par2   Number of test loops.
 *
 * @return N/A
 */
void lifo_thread1(void *par1, void *par2, void *par3)
{
	int i;
	int element_a[2];
	int element_b[2];
	int *pelement;
	int num_loops = (int) par2;

	ARG_UNUSED(par1);

	for (i = 0; i < num_loops / 2; i++) {
		pelement = (int *)k_lifo_get(&lifo1,
						      K_FOREVER);
		if (pelement[1] != 2 * i) {
			break;
		}
		element_a[1] = 2 * i;
		k_lifo_put(&lifo2, element_a);
		pelement = (int *)k_lifo_get(&lifo1,
						      K_FOREVER);
		if (pelement[1] != 2 * i + 1) {
			break;
		}
		element_b[1] = 2 * i + 1;
		k_lifo_put(&lifo2, element_b);
	}
	/* wait till it is safe to end: */
	k_fifo_get(&sync_fifo, K_FOREVER);
}


/**
 *
 * @brief Lifo test thread
 *
 * @param par1   Address of the counter.
 * @param par2   Number of test cycles.
 *
 * @return N/A
 */
void lifo_thread2(void *par1, void *par2, void *par3)
{
	int i;
	int element[2];
	int *pelement;
	int *pcounter = (int *)par1;
	int num_loops = (int) par2;

	for (i = 0; i < num_loops; i++) {
		element[1] = i;
		k_lifo_put(&lifo1, element);
		pelement = (int *)k_lifo_get(&lifo2,
						      K_FOREVER);
		if (pelement[1] != i) {
			break;
		}
		(*pcounter)++;
	}
	/* wait till it is safe to end: */
	k_fifo_get(&sync_fifo, K_FOREVER);
}

/**
 *
 * @brief Lifo test thread
 *
 * @param par1   Address of the counter.
 * @param par2   Number of test loops.
 *
 * @return N/A
 */
void lifo_thread3(void *par1, void *par2, void *par3)
{
	int i;
	int element[2];
	int *pelement;
	int *pcounter = (int *)par1;
	int num_loops = (int) par2;

	for (i = 0; i < num_loops; i++) {
		element[1] = i;
		k_lifo_put(&lifo1, element);
		while ((pelement = k_lifo_get(&lifo2,
							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 lifo_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,
			"LIFO #1");
	fprintf(output_file, sz_description,
			"\n\tk_lifo_init"
			"\n\tk_lifo_get(K_FOREVER)"
			"\n\tk_lifo_put");
	printf(sz_test_start_fmt);

	lifo_test_init();

	t = BENCH_START();

	k_thread_create(&thread_data1, thread_stack1, STACK_SIZE, lifo_thread1,
			 NULL, (void *) NUMBER_OF_LOOPS, NULL,
			 K_PRIO_COOP(3), 0, K_NO_WAIT);

	k_thread_create(&thread_data2, thread_stack2, STACK_SIZE, lifo_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,
			"LIFO #2");
	fprintf(output_file, sz_description,
			"\n\tk_lifo_init"
			"\n\tk_lifo_get(K_FOREVER)"
			"\n\tk_lifo_get(TICKS_NONE)"
			"\n\tk_lifo_put"
			"\n\tk_yield");
	printf(sz_test_start_fmt);

	lifo_test_init();

	t = BENCH_START();

	i = 0;

	k_thread_create(&thread_data1, thread_stack1, STACK_SIZE, lifo_thread1,
			 NULL, (void *) NUMBER_OF_LOOPS, NULL,
			 K_PRIO_COOP(3), 0, K_NO_WAIT);

	k_thread_create(&thread_data2, thread_stack2, STACK_SIZE, lifo_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,
			"LIFO #3");
	fprintf(output_file, sz_description,
			"\n\tk_lifo_init"
			"\n\tk_lifo_get(K_FOREVER)"
			"\n\tk_lifo_put"
			"\n\tk_lifo_get(K_FOREVER)"
			"\n\tk_lifo_put");
	printf(sz_test_start_fmt);

	lifo_test_init();

	t = BENCH_START();

	k_thread_create(&thread_data1, thread_stack1, STACK_SIZE, lifo_thread1,
			 NULL, (void *) NUMBER_OF_LOOPS, 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] = 2 * i;
		k_lifo_put(&lifo1, element);
		element[1] = 2 * i + 1;
		k_lifo_put(&lifo1, element);

		pelement = (int *)k_lifo_get(&lifo2,
						     K_FOREVER);
		if (pelement[1] != 2 * i + 1) {
			break;
		}
		pelement = (int *)k_lifo_get(&lifo2,
						     K_FOREVER);
		if (pelement[1] != 2 * 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;
}
