/* task.c - test microkernel task APIs */

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

/*
DESCRIPTION
This module tests the following task APIs:
    isr_task_id_get(), isr_task_priority_get(), task_id_get(), task_priority_get(),
    task_resume(), task_suspend(), task_priority_set(),
    task_sleep(), task_yield()
 */

#include <tc_util.h>
#include <zephyr.h>
#include <arch/cpu.h>
#include <irq_offload.h>

#include <util_test_common.h>

#define  RT_PRIO         5      /* RegressionTask prio - must match prj.mdef */
#define  HT_PRIO         10     /* HelperTask prio - must match prj.mdef */

#define  SLEEP_TIME SECONDS(1)

#define  CMD_TASKID    0
#define  CMD_PRIORITY  1

typedef struct {
	int  cmd;
	int  data;
} ISR_INFO;

static ISR_INFO   isrInfo;

static int tcRC = TC_PASS;         /* test case return code */
static int helperData;

static volatile int is_main_task_ready = 0;

#ifdef TEST_PRIV_TASKS
DEFINE_TASK(HT_TASKID, HT_PRIO, HelperTask, 2048, NULL);
DEFINE_TASK(RT_TASKID, RT_PRIO, RegressionTask, 2048, EXE);
#endif

/**
 *
 * @brief ISR handler to call isr_task_id_get() and isr_task_priority_get()
 *
 * @return N/A
 */

void isr_task_command_handler(void *data)
{
	ISR_INFO   *pInfo = (ISR_INFO *) data;
	int         value = -1;

	switch (pInfo->cmd) {
	case CMD_TASKID:
		value = (int)isr_task_id_get();
		break;

	case CMD_PRIORITY:
		value = isr_task_priority_get();
		break;
	}

	pInfo->data = value;
}

/**
 *
 * @brief Test isr_task_id_get() and isr_task_priority_get
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int isrAPIsTest(ktask_t taskId, kpriority_t taskPrio)
{
	isrInfo.cmd = CMD_TASKID;
	irq_offload(isr_task_command_handler, &isrInfo);
	if (isrInfo.data != (int)taskId) {
		TC_ERROR("isr_task_id_get() returned %d, not %d\n",
				 isrInfo.data, (int)taskId);
		return TC_FAIL;
	}

	isrInfo.cmd = CMD_PRIORITY;
	irq_offload(isr_task_command_handler, &isrInfo);
	if (isrInfo.data != taskPrio) {
		TC_ERROR("isr_task_priority_get() returned %d, not %d\n",
				 isrInfo.data, taskPrio);
		return TC_FAIL;
	}

	return TC_PASS;
}

/**
 *
 * @brief Test task_id_get() and task_priority_get() macros
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int taskMacrosTest(ktask_t taskId, int taskPrio)
{
	ktask_t taskIdValue;
	kpriority_t taskPrioValue;

	taskIdValue = task_id_get();
	if (taskIdValue != taskId) {
		TC_ERROR("task_id_get() returned 0x%x, not 0x%x\n",
				 (uint32_t)taskIdValue, (uint32_t)taskId);
		return TC_FAIL;
	}

	taskPrioValue = task_priority_get();
	if (taskPrioValue != taskPrio) {
		TC_ERROR("task_priority_get() returned %d, not %d\n",
				 taskPrioValue, taskPrio);
		return TC_FAIL;
	}

	return TC_PASS;
}

/**
 *
 * @brief Helper task portion to test setting the priority
 *
 * @return N/A
 */

void helperTaskSetPrioTest(void)
{
	task_sem_take(HT_SEM, TICKS_UNLIMITED);
	helperData = task_priority_get();     /* Helper task priority lowered by 5 */
	task_sem_give(RT_SEM);

	task_sem_take(HT_SEM, TICKS_UNLIMITED);
	helperData = task_priority_get();     /* Helper task prioirty raised by 10 */
	task_sem_give(RT_SEM);

	task_sem_take(HT_SEM, TICKS_UNLIMITED);
	helperData = task_priority_get();     /* Helper task prioirty restored */
	task_sem_give(RT_SEM);
}

/**
 *
 * @brief Test the task_priority_set() API
 *
 * @return N/A
 */

int taskSetPrioTest(void)
{
	int  rv;

	/* Lower the priority of the current task (RegressionTask) */
	task_priority_set(RT_TASKID, RT_PRIO + 2);
	rv = task_priority_get();
	if (rv != RT_PRIO + 2) {
		TC_ERROR("Expected priority to be changed to %d, not %d\n",
				 RT_PRIO + 2, rv);
		return TC_FAIL;
	}

	/* Raise the priority of the current task (RegressionTask) */
	task_priority_set(RT_TASKID, RT_PRIO - 2);
	rv = task_priority_get();
	if (rv != RT_PRIO - 2) {
		TC_ERROR("Expected priority to be changed to %d, not %d\n",
				 RT_PRIO - 2, rv);
		return TC_FAIL;
	}


	/* Restore the priority of the current task (RegressionTask) */
	task_priority_set(RT_TASKID, RT_PRIO);
	rv = task_priority_get();
	if (rv != RT_PRIO) {
		TC_ERROR("Expected priority to be changed to %d, not %d\n",
				 RT_PRIO, rv);
		return TC_FAIL;
	}


	/* Lower the priority of the helper task (HelperTask) */
	task_priority_set(HT_TASKID, HT_PRIO + 2);
	task_sem_give(HT_SEM);
	task_sem_take(RT_SEM, TICKS_UNLIMITED);
	if (helperData != HT_PRIO + 2) {
		TC_ERROR("Expected priority to be changed to %d, not %d\n",
				 HT_PRIO + 2, helperData);
		return TC_FAIL;
	}

	/* Raise the priority of the helper task (HelperTask) */
	task_priority_set(HT_TASKID, HT_PRIO - 2);
	task_sem_give(HT_SEM);
	task_sem_take(RT_SEM, TICKS_UNLIMITED);
	if (helperData != HT_PRIO - 2) {
		TC_ERROR("Expected priority to be changed to %d, not %d\n",
				 HT_PRIO - 2, helperData);
		return TC_FAIL;
	}


	/* Restore the priority of the helper task (HelperTask) */
	task_priority_set(HT_TASKID, HT_PRIO);
	task_sem_give(HT_SEM);
	task_sem_take(RT_SEM, TICKS_UNLIMITED);
	if (helperData != HT_PRIO) {
		TC_ERROR("Expected priority to be changed to %d, not %d\n",
				 HT_PRIO, helperData);
		return TC_FAIL;
	}

	return TC_PASS;
}

/**
 *
 * @brief Helper task portion to test task_sleep()
 *
 * @return N/A
 */

void helperTaskSleepTest(void)
{
	int32_t  firstTick;

	task_sem_take(HT_SEM, TICKS_UNLIMITED);

	firstTick = sys_tick_get_32();
	while (!is_main_task_ready) {
		/* busy work */
	}
	helperData = sys_tick_get_32() - firstTick;

	task_sem_give(RT_SEM);
}

/**
 *
 * @brief Test task_sleep()
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int taskSleepTest(void)
{
	int32_t  tick;

	task_sem_give(HT_SEM);

	/* align on tick boundary and get current tick */
	tick = sys_tick_get_32();
	while (tick == sys_tick_get_32()) {
	}

	/* compensate for the extra tick we just waited */
	++tick;

	task_sleep(SLEEP_TIME);

	tick = sys_tick_get_32() - tick;

	is_main_task_ready = 1;
	task_sem_take(RT_SEM, TICKS_UNLIMITED);

	/*
	 * By design this should be exact, but at least one cycle of
	 * slop is required experimentally on Qemu.
	 */
	if (tick < SLEEP_TIME || tick > SLEEP_TIME + 1) {
		TC_ERROR("task_sleep() slept for %d ticks, not %d\n", tick, SLEEP_TIME);
		return TC_FAIL;
	}

	/*
	 * Similarly check that the helper task ran for approximately
	 * SLEEP_TIME. On QEMU, when the host CPU is overloaded, it
	 * has been observed that the tick count can be missed by 1 on
	 * either side. Allow for 2 ticks to be sure.  This check is
	 * only there to make sure that the helper task did run for
	 * approximately the whole time the main task was sleeping.
	 */
	const int tick_error_allowed = 2;
	if (helperData > SLEEP_TIME + tick_error_allowed ||
		helperData < SLEEP_TIME - tick_error_allowed) {
		TC_ERROR("helper task should have run for around %d ticks "
				 "(+/-%d), but ran for %d ticks\n",
					SLEEP_TIME, tick_error_allowed, helperData);
		return TC_FAIL;
	}

	return TC_PASS;
}

/**
 *
 * @brief Helper task portion of task_yield() test
 *
 * @return N/A
 */

void helperTaskYieldTest(void)
{
	int  i;
	task_sem_take(HT_SEM, TICKS_UNLIMITED);

	for (i = 0; i < 5; i++) {
		helperData++;
		task_yield();
	}

	task_sem_give(RT_SEM);
}

/**
 *
 * @brief Test task_yield()
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int taskYieldTest(void)
{
	int  prevHelperData;
	int  i;

	helperData = 0;

	/* 1st raise the priority of the helper task */
	task_priority_set(HT_TASKID, RT_PRIO);
	task_sem_give(HT_SEM);

	for (i = 0; i < 5; i++) {
		prevHelperData = helperData;
		task_yield();

		if (helperData == prevHelperData) {
			TC_ERROR("Iter %d.  helperData did not change (%d)\n",
					 i + 1, helperData);
			return TC_FAIL;
		}
	}

	/* Restore helper task priority */
	task_priority_set(HT_TASKID, HT_PRIO);

	/* Ensure that the helper task finishes */
	task_sem_take(RT_SEM, TICKS_UNLIMITED);

	return TC_PASS;
}

/**
 *
 * @brief Helper task portion of task_suspend() and
 *                         task_resume() tests
 *
 * @return N/A
 */

void helperTaskSuspendTest(void)
{
	helperData++;

	task_sem_take(HT_SEM, TICKS_UNLIMITED);
}

/**
 *
 * @brief Test task_suspend() and task_resume()
 *
 * This test suspends the helper task.  Once it is suspended, the main task
 * (RegressionTask) sleeps for one second.  If the helper task is truly
 * suspended, it will not execute and modify <helperData>.  Once confirmed,
 * the helper task is resumed, and the main task sleeps once more.  If the
 * helper task has truly resumed, it will modify <helperData>.
 *
 * @return TC_PASS on success or TC_FAIL on failure
 */

int taskSuspendTest(void)
{
	int  prevHelperData;

	task_suspend(HT_TASKID);    /* Suspend the helper task */

	prevHelperData = helperData;
	task_sleep(SLEEP_TIME);

	if (prevHelperData != helperData) {
		TC_ERROR("Helper task did not suspend!\n");
		return TC_FAIL;
	}

	task_resume(HT_TASKID);
	task_sleep(SLEEP_TIME);

	if (prevHelperData == helperData) {
		TC_ERROR("Helper task did not resume!\n");
		return TC_FAIL;
	}

	task_sem_give(HT_SEM);
	return TC_PASS;
}

/**
 *
 * @brief Helper task to test the task APIs
 *
 * @return  N/A
 */

void HelperTask(void)
{
	int  rv;

	task_sem_take(HT_SEM, TICKS_UNLIMITED);
	rv = isrAPIsTest(HT_TASKID, HT_PRIO);
	if (rv != TC_PASS) {
		tcRC = TC_FAIL;
		return;
	}
	task_sem_give(RT_SEM);

	task_sem_take(HT_SEM, TICKS_UNLIMITED);
	rv = taskMacrosTest(HT_TASKID, HT_PRIO);
	if (rv != TC_PASS) {
		tcRC = TC_FAIL;
		return;
	}
	task_sem_give(RT_SEM);

	helperTaskSetPrioTest();

	helperTaskSleepTest();

	helperTaskYieldTest();

	helperTaskSuspendTest();
}

/**
 *
 * @brief Main task to test the task APIs
 *
 * @return  N/A
 */

void RegressionTask(void)
{
	int    rv;

	TC_START("Test Microkernel Task API");

	PRINT_LINE;

	task_start(HT_TASKID);

	TC_PRINT("Testing isr_task_id_get() and isr_task_priority_get()\n");
	rv = isrAPIsTest(RT_TASKID, RT_PRIO);
	if (rv != TC_PASS) {
		tcRC = TC_FAIL;
		goto errorReturn;
	}

	task_sem_give(HT_SEM);
	task_sem_take(RT_SEM, TICKS_UNLIMITED);

	TC_PRINT("Testing task_id_get() and task_priority_get()\n");
	rv = taskMacrosTest(RT_TASKID, RT_PRIO);
	if (rv != TC_PASS) {
		tcRC = TC_FAIL;
		goto errorReturn;
	}

	task_sem_give(HT_SEM);
	task_sem_take(RT_SEM, TICKS_UNLIMITED);

	TC_PRINT("Testing task_priority_set()\n");
	if (taskSetPrioTest() != TC_PASS) {
		tcRC = TC_FAIL;
		goto errorReturn;
	}

	TC_PRINT("Testing task_sleep()\n");
	if (taskSleepTest() != TC_PASS) {
		tcRC = TC_FAIL;
		goto errorReturn;
	}

	TC_PRINT("Testing task_yield()\n");
	if (taskYieldTest() != TC_PASS) {
		tcRC = TC_FAIL;
		goto errorReturn;
	}

	TC_PRINT("Testing task_suspend() and task_resume()\n");
	if (taskSuspendTest() != TC_PASS) {
		tcRC = TC_FAIL;
		goto errorReturn;
	}

errorReturn:
	TC_END_RESULT(tcRC);
	TC_END_REPORT(tcRC);
}  /* RegressionTask */
