/* 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)
{
	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,
			"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_spawn(thread_stack1, STACK_SIZE, lifo_thread1,
			 NULL, (void *) NUMBER_OF_LOOPS, NULL,
			 K_PRIO_COOP(3), 0, K_NO_WAIT);

	k_thread_spawn(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_spawn(thread_stack1, STACK_SIZE, lifo_thread1,
			 NULL, (void *) NUMBER_OF_LOOPS, NULL,
			 K_PRIO_COOP(3), 0, K_NO_WAIT);

	k_thread_spawn(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_spawn(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;
}
