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

/*
 * Copyright (c) 2012-2014 Wind River Systems, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
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         10     /* RegressionTask prio - must match prj.mdef */
#define  HT_PRIO         20     /* 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
/* Note this is in reverse order of what is defined under
 * test_task/prj.mdef. This is due to compiler filling linker
 * section like a stack. This is to preserve the same order
 * in memory as test_task.
 */
DEFINE_TASK(RT_TASKID, 10, RegressionTask, 2048, EXE);
DEFINE_TASK(HT_TASKID, 20, HelperTask, 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 = 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(int taskId, int taskPrio)
{
	isrInfo.cmd = CMD_TASKID;
	irq_offload(isr_task_command_handler, &isrInfo);
	if (isrInfo.data != taskId) {
		TC_ERROR("isr_task_id_get() returned %d, not %d\n",
				 isrInfo.data, 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(int taskId, int taskPrio)
{
	int  value;

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

	value = task_priority_get();
	if (value != taskPrio) {
		TC_ERROR("task_priority_get() returned %d, not %d\n",
				 value, 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 + 5);
	rv = task_priority_get();
	if (rv != RT_PRIO + 5) {
		TC_ERROR("Expected priority to be changed to %d, not %d\n",
				 RT_PRIO + 5, rv);
		return TC_FAIL;
	}

	/* Raise the priority of the current task (RegressionTask) */
	task_priority_set(RT_TASKID, RT_PRIO - 5);
	rv = task_priority_get();
	if (rv != RT_PRIO - 5) {
		TC_ERROR("Expected priority to be changed to %d, not %d\n",
				 RT_PRIO - 5, 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 + 5);
	task_sem_give(HT_SEM);
	task_sem_take(RT_SEM, TICKS_UNLIMITED);
	if (helperData != HT_PRIO + 5) {
		TC_ERROR("Expected priority to be changed to %d, not %d\n",
				 HT_PRIO + 5, helperData);
		return TC_FAIL;
	}

	/* Raise the priority of the helper task (HelperTask) */
	task_priority_set(HT_TASKID, HT_PRIO - 5);
	task_sem_give(HT_SEM);
	task_sem_take(RT_SEM, TICKS_UNLIMITED);
	if (helperData != HT_PRIO - 5) {
		TC_ERROR("Expected priority to be changed to %d, not %d\n",
				 HT_PRIO - 5, 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);

	if (tick != SLEEP_TIME) {
		TC_ERROR("task_sleep() slept for %d ticks, not %d\n", tick, SLEEP_TIME);
		return TC_FAIL;
	}

	/*
	 * 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 */
