/* stack.c */

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

#include "syskernel.h"

struct k_stack  stack_1;
struct k_stack  stack_2;

u32_t stack1[2];
u32_t stack2[2];

/**
 *
 * @brief Initialize stacks for the test
 *
 * @return N/A
 *
 */
void stack_test_init(void)
{
	k_stack_init(&stack_1, stack1, 2);
	k_stack_init(&stack_2, stack2, 2);
}


/**
 *
 * @brief Stack test thread
 *
 * @param par1   Ignored parameter.
 * @param par2   Number of test loops.
 *
 * @return N/A
 *
 */
void stack_thread1(void *par1, void *par2, void *par3)
{
	int num_loops = ((int) par2 / 2);
	int i;
	u32_t data;

	ARG_UNUSED(par1);
	ARG_UNUSED(par3);

	for (i = 0; i < num_loops; i++) {
		k_stack_pop(&stack_1, &data, K_FOREVER);
		if (data != 2 * i) {
			break;
		}
		data = 2 * i;
		k_stack_push(&stack_2, data);
		k_stack_pop(&stack_1, &data, K_FOREVER);
		if (data != 2 * i + 1) {
			break;
		}
		data = 2 * i + 1;
		k_stack_push(&stack_2, data);
	}
}


/**
 *
 * @brief Stack test thread
 *
 * @param par1   Address of the counter.
 * @param par2   Number of test cycles.
 *
 * @return N/A
 *
 */
void stack_thread2(void *par1, void *par2, void *par3)
{
	int i;
	u32_t data;
	int *pcounter = (int *)par1;
	int num_loops = (int) par2;

	ARG_UNUSED(par3);

	for (i = 0; i < num_loops; i++) {
		data = i;
		k_stack_push(&stack_1, data);
		k_stack_pop(&stack_2, &data, K_FOREVER);
		if (data != i) {
			break;
		}
		(*pcounter)++;
	}
}


/**
 *
 * @brief Stack test thread
 *
 * @param par1   Address of the counter.
 * @param par2   Number of test cycles.
 *
 * @return N/A
 *
 */
void stack_thread3(void *par1, void *par2, void *par3)
{
	int i;
	u32_t data;
	int *pcounter = (int *)par1;
	int num_loops = (int) par2;

	ARG_UNUSED(par3);

	for (i = 0; i < num_loops; i++) {
		data = i;
		k_stack_push(&stack_1, data);
		data = 0xffffffff;

		while (k_stack_pop(&stack_2, &data,
					     K_NO_WAIT) != 0) {
			k_yield();
		}
		if (data != i) {
			break;
		}
		(*pcounter)++;
	}
}


/**
 *
 * @brief The main test entry
 *
 * @return 1 if success and 0 on failure
 *
 */
int stack_test(void)
{
	u32_t t;
	int i = 0;
	int return_value = 0;

	/* test get wait & put stack functions between co-op threads */
	fprintf(output_file, sz_test_case_fmt,
			"Stack #1");
	fprintf(output_file, sz_description,
			"\n\tk_stack_init"
			"\n\tk_stack_pop(K_FOREVER)"
			"\n\tk_stack_push");
	printf(sz_test_start_fmt);

	stack_test_init();

	t = BENCH_START();

	k_thread_create(&thread_data1, thread_stack1, STACK_SIZE, stack_thread1,
			 0, (void *) NUMBER_OF_LOOPS, NULL,
			 K_PRIO_COOP(3), 0, K_NO_WAIT);
	k_thread_create(&thread_data2, thread_stack2, STACK_SIZE, stack_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);

	/* test get/yield & put stack functions between co-op threads */
	fprintf(output_file, sz_test_case_fmt,
			"Stack #2");
	fprintf(output_file, sz_description,
			"\n\tk_stack_init"
			"\n\tk_stack_pop(K_FOREVER)"
			"\n\tk_stack_pop"
			"\n\tk_stack_push"
			"\n\tk_yield");
	printf(sz_test_start_fmt);

	stack_test_init();

	t = BENCH_START();

	i = 0;
	k_thread_create(&thread_data1, thread_stack1, STACK_SIZE, stack_thread1,
			 0, (void *) NUMBER_OF_LOOPS, NULL,
			 K_PRIO_COOP(3), 0, K_NO_WAIT);
	k_thread_create(&thread_data2, thread_stack2, STACK_SIZE, stack_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);

	/* test get wait & put stack functions across co-op and premptive
	 * threads
	 */
	fprintf(output_file, sz_test_case_fmt,
			"Stack #3");
	fprintf(output_file, sz_description,
			"\n\tk_stack_init"
			"\n\tk_stack_pop(K_FOREVER)"
			"\n\tk_stack_push"
			"\n\tk_stack_pop(K_FOREVER)"
			"\n\tk_stack_push");
	printf(sz_test_start_fmt);

	stack_test_init();

	t = BENCH_START();

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

	for (i = 0; i < NUMBER_OF_LOOPS / 2; i++) {
		u32_t data;

		data = 2 * i;
		k_stack_push(&stack_1, data);
		data = 2 * i + 1;
		k_stack_push(&stack_1, data);

		k_stack_pop(&stack_2, &data, K_FOREVER);
		if (data != 2 * i + 1) {
			break;
		}
		k_stack_pop(&stack_2, &data, K_FOREVER);
		if (data != 2 * i) {
			break;
		}
	}

	t = TIME_STAMP_DELTA_GET(t);

	return_value += check_result(i * 2, t);

	return return_value;
}
