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

/*
 * @file
 * @brief Test nanokernel semaphore APIs
 *
 * This module tests four basic scenarios with the usage of the following
 * semaphore routines:
 *
 * nano_sem_init
 * nano_fiber_sem_give, nano_fiber_sem_take
 * nano_task_sem_give, nano_task_sem_take
 * nano_isr_sem_give, nano_isr_sem_take
 *
 * Scenario #1:
 * A task, fiber or ISR does not wait for the semaphore when taking it.
 *
 * Scenario #2:
 * A task or fiber must wait for the semaphore to be given before it gets it.
 *
 * Scenario #3:
 * Multiple fibers pend on the same semaphore.
 *
 * Scenario #4:
 * Timeout scenarios with multiple semaphores and fibers.
 */

#include <tc_util.h>
#include <arch/cpu.h>
#include <misc/util.h>
#include <irq_offload.h>

#include <util_test_common.h>

#if defined(CONFIG_ASSERT) && defined(CONFIG_DEBUG)
#define FIBER_STACKSIZE	(512 + CONFIG_TEST_EXTRA_STACKSIZE)
#else
#define FIBER_STACKSIZE	(384 + CONFIG_TEST_EXTRA_STACKSIZE)
#endif

#define FIBER_PRIORITY     4

typedef struct {
	struct nano_sem *sem;    /* ptr to semaphore */
	int              data;   /* data */
} ISR_SEM_INFO;

typedef enum {
	STS_INIT = -1,
	STS_TASK_WOKE_FIBER,
	STS_FIBER_WOKE_TASK,
	STS_ISR_WOKE_TASK
} SEM_TEST_STATE;

static SEM_TEST_STATE  semTestState;
static ISR_SEM_INFO    isrSemInfo;
static struct nano_sem        testSem;
static int             fiberDetectedFailure = 0;

static struct nano_timer     timer;
static void *timerData[1];

static char __stack fiberStack[FIBER_STACKSIZE];

static struct nano_sem multi_waiters;
static struct nano_sem reply_multi_waiters;

/**
 *
 * @brief Take a semaphore
 *
 * This routine is the ISR handler for _trigger_nano_isr_sem_take().  It takes a
 * semaphore within the context of an ISR.
 *
 * @param data    pointer to ISR handler parameter
 *
 * @return N/A
 */

static void my_isr_sem_take(void *data)
{
	ISR_SEM_INFO *pInfo = (ISR_SEM_INFO *) data;

	pInfo->data = nano_isr_sem_take(pInfo->sem, TICKS_NONE);
}

static void _trigger_nano_isr_sem_take(void)
{
	irq_offload(my_isr_sem_take, &isrSemInfo);
}

/**
 *
 * @brief Give a semaphore
 *
 * This routine is the ISR handler for _trigger_nano_isr_sem_take().  It gives a
 * semaphore within the context of an ISR.
 *
 * @param data    pointer to ISR handler parameter
 *
 * @return N/A
 */

static void my_isr_sem_give(void *data)
{
	ISR_SEM_INFO *pInfo = (ISR_SEM_INFO *) data;

	nano_isr_sem_give(pInfo->sem);
	pInfo->data = 1;     /* Indicate semaphore has been given */
}

static void _trigger_nano_isr_sem_give(void)
{
	irq_offload(my_isr_sem_give, &isrSemInfo);
}

/**
 *
 * @brief Give and take the semaphore in a fiber without blocking
 *
 * This test gives and takes the test semaphore in a fiber
 * without blocking on the semaphore.
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int testSemFiberNoWait(void)
{
	int  i;

	TC_PRINT("Giving and taking a semaphore in a fiber (non-blocking)\n");

	/*
	 * Give the semaphore many times and then make sure that it can only be
	 * taken that many times.
	 */

	for (i = 0; i < 32; i++) {
		nano_fiber_sem_give(&testSem);
	}

	for (i = 0; i < 32; i++) {
		if (nano_fiber_sem_take(&testSem, TICKS_NONE) != 1) {
			TC_ERROR(" *** Expected nano_fiber_sem_take() to succeed, not fail\n");
			goto errorReturn;
		}
	}

	if (nano_fiber_sem_take(&testSem, TICKS_NONE) != 0) {
		TC_ERROR(" *** Expected  nano_fiber_sem_take() to fail, not succeed\n");
		goto errorReturn;
	}

	return TC_PASS;

errorReturn:
	fiberDetectedFailure = 1;
	return TC_FAIL;
}

/**
 *
 * @brief Entry point for the fiber portion of the semaphore tests
 *
 * NOTE: The fiber portion of the tests have higher priority than the task
 * portion of the tests.
 *
 * @param arg1    unused
 * @param arg2    unused
 *
 * @return N/A
 */

static void fiberEntry(int arg1, int arg2)
{
	int  rv;      /* return value from a test */

	ARG_UNUSED(arg1);
	ARG_UNUSED(arg2);

	rv = testSemFiberNoWait();
	if (rv != TC_PASS) {
		return;
	}

	/*
	 * At this point <testSem> is not available.  Wait for <testSem> to become
	 * available (the main task will give it).
	 */

	nano_fiber_sem_take(&testSem, TICKS_UNLIMITED);

	semTestState = STS_TASK_WOKE_FIBER;

	/*
	 * Delay for two seconds.  This gives the main task time to print
	 * any messages (very important if I/O link is slow!), and wait
	 * on <testSem>.  Once the delay is done, this fiber will give <testSem>
	 * thus waking the main task.
	 */

	nano_fiber_timer_start(&timer, SECONDS(2));
	nano_fiber_timer_test(&timer, TICKS_UNLIMITED);

	/*
	 * The main task is now waiting on <testSem>.  Give the semaphore <testSem>
	 * to wake it.
	 */

	nano_fiber_sem_give(&testSem);

	/*
	 * Some small delay must be done so that the main task can process the
	 * semaphore signal.
	 */

	semTestState = STS_FIBER_WOKE_TASK;

	nano_fiber_timer_start(&timer, SECONDS(2));
	nano_fiber_timer_test(&timer, TICKS_UNLIMITED);

	/*
	 * The main task should be waiting on <testSem> again.  This time, instead
	 * of giving the semaphore from the semaphore, give it from an ISR to wake
	 * the main task.
	 */

	isrSemInfo.data = 0;
	isrSemInfo.sem = &testSem;
	_trigger_nano_isr_sem_give();

	if (isrSemInfo.data == 1) {
		semTestState = STS_ISR_WOKE_TASK;
	}
}

/**
 *
 * @brief Initialize nanokernel objects
 *
 * This routine initializes the nanokernel objects used in the semaphore tests.
 *
 * @return N/A
 */

void initNanoObjects(void)
{
	nano_sem_init(&testSem);
	nano_sem_init(&multi_waiters);
	nano_sem_init(&reply_multi_waiters);
	nano_timer_init(&timer, timerData);

	TC_PRINT("Nano objects initialized\n");
}

/**
 *
 * @brief Give and take the semaphore in an ISR without blocking
 *
 * This test gives and takes the test semaphore in the context of an ISR without
 * blocking on the semaphore.
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int testSemIsrNoWait(void)
{
	int  i;

	TC_PRINT("Giving and taking a semaphore in an ISR (non-blocking)\n");

	/*
	 * Give the semaphore many times and then make sure that it can only be
	 * taken that many times.
	 */

	isrSemInfo.sem = &testSem;
	for (i = 0; i < 32; i++) {
		_trigger_nano_isr_sem_give();
	}

	for (i = 0; i < 32; i++) {
		isrSemInfo.data = 0;
		_trigger_nano_isr_sem_take();
		if (isrSemInfo.data != 1) {
			TC_ERROR(" *** Expected nano_isr_sem_take() to succeed, not fail\n");
			goto errorReturn;
		}
	}

	_trigger_nano_isr_sem_take();
	if (isrSemInfo.data != 0) {
		TC_ERROR(" *** Expected  nano_isr_sem_take() to fail, not succeed!\n");
		goto errorReturn;
	}

	return TC_PASS;

errorReturn:
	return TC_FAIL;
}

/**
 *
 * @brief Give and take the semaphore in a task without blocking
 *
 * This test gives and takes the test semaphore in a task without
 * blocking on the semaphore.
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int testSemTaskNoWait(void)
{
	int  i;     /* loop counter */

	TC_PRINT("Giving and taking a semaphore in a task (non-blocking)\n");

	/*
	 * Give the semaphore many times and then make sure that it can only be
	 * taken that many times.
	 */

	for (i = 0; i < 32; i++) {
		nano_task_sem_give(&testSem);
	}

	for (i = 0; i < 32; i++) {
		if (nano_task_sem_take(&testSem, TICKS_NONE) != 1) {
			TC_ERROR(" *** Expected nano_task_sem_take() to succeed, not fail\n");
			goto errorReturn;
		}
	}

	if (nano_task_sem_take(&testSem, TICKS_NONE) != 0) {
		TC_ERROR(" *** Expected  nano_task_sem_take() to fail, not succeed!\n");
		goto errorReturn;
	}

	return TC_PASS;

errorReturn:
	return TC_FAIL;
}

/**
 *
 * @brief Perform tests that wait on a semaphore
 *
 * This routine works with fiberEntry() to perform the tests that wait on
 * a semaphore.
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int testSemWait(void)
{
	if (fiberDetectedFailure != 0) {
		TC_ERROR(" *** Failure detected in the fiber.");
		return TC_FAIL;
	}

	nano_task_sem_give(&testSem);    /* Wake the fiber. */

	if (semTestState != STS_TASK_WOKE_FIBER) {
		TC_ERROR(" *** Expected task to wake fiber.  It did not.\n");
		return TC_FAIL;
	}

	TC_PRINT("Semaphore from the task woke the fiber\n");

	nano_task_sem_take(&testSem, TICKS_UNLIMITED);   /* Wait on <testSem> */

	if (semTestState != STS_FIBER_WOKE_TASK) {
		TC_ERROR(" *** Expected fiber to wake task.  It did not.\n");
		return TC_FAIL;
	}

	TC_PRINT("Semaphore from the fiber woke the task\n");

	nano_task_sem_take(&testSem, TICKS_UNLIMITED);  /* Wait on <testSem> again. */

	if (semTestState != STS_ISR_WOKE_TASK) {
		TC_ERROR(" *** Expected ISR to wake task.  It did not.\n");
		return TC_FAIL;
	}

	TC_PRINT("Semaphore from the ISR woke the task.\n");
	return TC_PASS;
}

/*
 * Multiple-waiters test
 *
 * NUM_WAITERS fibers pend on the multi_waiters semaphore, then the task give
 * the semaphore NUM_WAITERS times. Each time, the first fiber in the queue
 * wakes up, is context-switched to, and gives the reply_multi_waiters
 * semaphore, for a total of NUM_WAITERS times. The task finally must be able
 * to obtain the reply_multi_waiters semaphore NUM_WAITERS times.
 */
#define NUM_WAITERS 3
static char __stack fiber_multi_waiters_stacks[NUM_WAITERS][FIBER_STACKSIZE];

/**
 *
 * @brief Fiber entry point for multiple-waiters test
 *
 * @return N/A
 */

static void fiber_multi_waiters(int arg1, int arg2)
{
	TC_PRINT("multiple-waiter fiber %d trying to get semaphore...\n", arg1);
	nano_fiber_sem_take(&multi_waiters, TICKS_UNLIMITED);
	TC_PRINT("multiple-waiter fiber %d acquired semaphore, sending reply\n",
				arg1);
	nano_fiber_sem_give(&reply_multi_waiters);
}

/**
 *
 * @brief Task part of multiple-waiter test, repeatable
 *
 * @return N/A
 */

static int do_test_multiple_waiters(void)
{
	int ii;

	/* pend all fibers one the same semaphore */
	for (ii = 0; ii < NUM_WAITERS; ii++) {
		task_fiber_start(fiber_multi_waiters_stacks[ii], FIBER_STACKSIZE,
							fiber_multi_waiters, ii, 0, FIBER_PRIORITY, 0);
	}

	/* wake up all the fibers: the task is preempted each time */
	for (ii = 0; ii < NUM_WAITERS; ii++) {
		nano_task_sem_give(&multi_waiters);
	}

	/* reply_multi_waiters will have been given once for each fiber */
	for (ii = 0; ii < NUM_WAITERS; ii++) {
		if (!nano_task_sem_take(&reply_multi_waiters, TICKS_NONE)) {
			TC_ERROR(" *** Cannot take sem supposedly given by waiters.\n");
			return TC_FAIL;
		}
	}

	TC_PRINT("Task took multi-waiter reply semaphore %d times, as expected.\n",
				NUM_WAITERS);

	if (nano_task_sem_take(&multi_waiters, TICKS_NONE)) {
		TC_ERROR(" *** multi_waiters should have been empty.\n");
		return TC_FAIL;
	}

	if (nano_task_sem_take(&reply_multi_waiters, TICKS_NONE)) {
		TC_ERROR(" *** reply_multi_waiters should have been empty.\n");
		return TC_FAIL;
	}

	return TC_PASS;
}

/**
 *
 * @brief Entry point for multiple-waiters test
 *
 * @return N/A
 */

static int test_multiple_waiters(void)
{
	TC_PRINT("First pass\n");
	if (do_test_multiple_waiters() == TC_FAIL) {
		TC_ERROR(" *** First pass test failed.\n");
		return TC_FAIL;
	}

	/*
	 * Verify a wait q that has been emptied has been reset correctly, so
	 * redo the test.
	 */

	TC_PRINT("Second pass\n");
	if (do_test_multiple_waiters() == TC_FAIL) {
		TC_ERROR(" *** Second pass test failed.\n");
		return TC_FAIL;
	}

	return TC_PASS;
}

/* timeout tests
 *
 * Test the nano_xxx_sem_wait_timeout() APIs.
 *
 * First, the task waits with a timeout and times out. Then it wait with a
 * timeout, but gets the semaphore in time.
 *
 * Then, multiple timeout tests are done for the fibers, to test the ordering
 * of queueing/dequeueing when timeout occurs, first on one semaphore, then on
 * multiple semaphores.
 *
 * Finally, multiple fibers pend on one semaphore, and they all get the
 * semaphore in time, except the last one: this tests that the timeout is
 * recomputed correctly when timeouts are aborted.
 */

#include <tc_nano_timeout_common.h>

static struct nano_sem sem_timeout[2];
struct nano_fifo timeout_order_fifo;

struct reply_packet {
	void *link_in_fifo;
	int reply;
};

struct timeout_order_data {
	void *link_in_fifo;
	struct nano_sem *sem;
	int32_t timeout;
	int timeout_order;
	int q_order;
};

struct timeout_order_data timeout_order_data[] = {
	{0, &sem_timeout[0], TIMEOUT(2), 2, 0},
	{0, &sem_timeout[0], TIMEOUT(4), 4, 1},
	{0, &sem_timeout[0], TIMEOUT(0), 0, 2},
	{0, &sem_timeout[0], TIMEOUT(1), 1, 3},
	{0, &sem_timeout[0], TIMEOUT(3), 3, 4},
};

struct timeout_order_data timeout_order_data_mult_sem[] = {
	{0, &sem_timeout[1], TIMEOUT(0), 0, 0},
	{0, &sem_timeout[0], TIMEOUT(3), 3, 1},
	{0, &sem_timeout[0], TIMEOUT(5), 5, 2},
	{0, &sem_timeout[1], TIMEOUT(8), 8, 3},
	{0, &sem_timeout[1], TIMEOUT(7), 7, 4},
	{0, &sem_timeout[0], TIMEOUT(1), 1, 5},
	{0, &sem_timeout[0], TIMEOUT(6), 6, 6},
	{0, &sem_timeout[0], TIMEOUT(2), 2, 7},
	{0, &sem_timeout[1], TIMEOUT(4), 4, 8},
};

#define TIMEOUT_ORDER_NUM_FIBERS ARRAY_SIZE(timeout_order_data_mult_sem)
static char __stack timeout_stacks[TIMEOUT_ORDER_NUM_FIBERS][FIBER_STACKSIZE];

/* a fiber sleeps then gives a semaphore */
static void test_fiber_give_timeout(int sem, int timeout)
{
	fiber_sleep((int32_t)timeout);
	nano_fiber_sem_give((struct nano_sem *)sem);
}

/* a fiber pends on a semaphore then times out */
static void test_fiber_pend_and_timeout(int data, int unused)
{
	struct timeout_order_data *the_data = (void *)data;
	int32_t orig_ticks = sys_tick_get();
	int rv;

	ARG_UNUSED(unused);

	rv = nano_fiber_sem_take(the_data->sem, the_data->timeout);
	if (rv) {
		TC_ERROR(" *** timeout of %d did not time out.\n",
					the_data->timeout);
		return;
	}
	if (!is_timeout_in_range(orig_ticks, the_data->timeout)) {
		return;
	}

	nano_fiber_fifo_put(&timeout_order_fifo, the_data);
}

/* the task spins several fibers that pend and timeout on sempahores */
static int test_multiple_fibers_pending(struct timeout_order_data *test_data,
										int test_data_size)
{
	int ii;

	for (ii = 0; ii < test_data_size; ii++) {
		task_fiber_start(timeout_stacks[ii], FIBER_STACKSIZE,
							test_fiber_pend_and_timeout,
							(int)&test_data[ii], 0,
							FIBER_PRIORITY, 0);
	}

	for (ii = 0; ii < test_data_size; ii++) {
		struct timeout_order_data *data =
			nano_task_fifo_get(&timeout_order_fifo, TICKS_UNLIMITED);

		if (data->timeout_order == ii) {
			TC_PRINT(" got fiber (q order: %d, t/o: %d, sem: %p) as expected\n",
						data->q_order, data->timeout, data->sem);
		} else {
			TC_ERROR(" *** fiber %d woke up, expected %d\n",
						data->timeout_order, ii);
			return TC_FAIL;
		}
	}

	return TC_PASS;
}

/* a fiber pends on a semaphore with a timeout and gets the semaphore in time */
static void test_fiber_pend_and_get_sem(int data, int unused)
{
	struct timeout_order_data *the_data = (void *)data;
	int rv;

	ARG_UNUSED(unused);

	rv = nano_fiber_sem_take(the_data->sem, the_data->timeout);
	if (!rv) {
		TC_PRINT(" *** fiber (q order: %d, t/o: %d, sem: %p) timed out!\n",
						the_data->q_order, the_data->timeout, the_data->sem);
		return;
	}

	nano_fiber_fifo_put(&timeout_order_fifo, the_data);
}

/* the task spins fibers that get the sem in time, except the last one */
static int test_multiple_fibers_get_sem(struct timeout_order_data *test_data,
										int test_data_size)
{
	struct timeout_order_data *data;
	int ii;

	for (ii = 0; ii < test_data_size-1; ii++) {
		task_fiber_start(timeout_stacks[ii], FIBER_STACKSIZE,
							test_fiber_pend_and_get_sem,
							(int)&test_data[ii], 0,
							FIBER_PRIORITY, 0);
	}
	task_fiber_start(timeout_stacks[ii], FIBER_STACKSIZE,
						test_fiber_pend_and_timeout,
						(int)&test_data[ii], 0,
						FIBER_PRIORITY, 0);

	for (ii = 0; ii < test_data_size-1; ii++) {
		nano_task_sem_give(test_data[ii].sem);

		data = nano_task_fifo_get(&timeout_order_fifo, TICKS_UNLIMITED);

		if (data->q_order == ii) {
			TC_PRINT(" got fiber (q order: %d, t/o: %d, sem: %p) as expected\n",
						data->q_order, data->timeout, data->sem);
		} else {
			TC_ERROR(" *** fiber %d woke up, expected %d\n",
						data->q_order, ii);
			return TC_FAIL;
		}
	}

	data = nano_task_fifo_get(&timeout_order_fifo, TICKS_UNLIMITED);
	if (data->q_order == ii) {
		TC_PRINT(" got fiber (q order: %d, t/o: %d, sem: %p) as expected\n",
					data->q_order, data->timeout, data->sem);
	} else {
		TC_ERROR(" *** fiber %d woke up, expected %d\n",
					data->timeout_order, ii);
		return TC_FAIL;
	}

	return TC_PASS;
}

static void test_fiber_ticks_special_values(int packet, int special_value)
{
	struct reply_packet *reply_packet = (void *)packet;

	reply_packet->reply =
		nano_fiber_sem_take(&sem_timeout[0], special_value);
	nano_fiber_fifo_put(&timeout_order_fifo, reply_packet);
}

/* the timeout test entry point */
static int test_timeout(void)
{
	int64_t orig_ticks;
	int32_t timeout;
	int rv;
	int test_data_size;
	struct reply_packet reply_packet;

	nano_sem_init(&sem_timeout[0]);
	nano_sem_init(&sem_timeout[1]);
	nano_fifo_init(&timeout_order_fifo);

	/* test nano_task_sem_take() with timeout */
	timeout = 10;
	orig_ticks = sys_tick_get();
	rv = nano_task_sem_take(&sem_timeout[0], timeout);
	if (rv) {
		TC_ERROR(" *** timeout of %d did not time out.\n", timeout);
		return TC_FAIL;
	}
	if ((sys_tick_get() - orig_ticks) < timeout) {
		TC_ERROR(" *** task did not wait long enough on timeout of %d.\n",
					timeout);
		return TC_FAIL;
	}

	/* test nano_task_sem_take() with timeout of 0 */

	rv = nano_task_sem_take(&sem_timeout[0], 0);
	if (rv) {
		TC_ERROR(" *** timeout of 0 did not time out.\n");
		return TC_FAIL;
	}

	/* test nano_task_sem_take() with timeout > 0 */

	TC_PRINT("test nano_task_sem_take() with timeout > 0\n");

	timeout = 3;
	orig_ticks = sys_tick_get();

	rv = nano_task_sem_take(&sem_timeout[0], timeout);

	if (rv) {
		TC_ERROR(" *** timeout of %d did not time out.\n",
				timeout);
		return TC_FAIL;
	}

	if (!is_timeout_in_range(orig_ticks, timeout)) {
		return TC_FAIL;
	}

	TC_PRINT("nano_task_sem_take() timed out as expected\n");

	/*
	 * test nano_task_sem_take() with a timeout and fiber that gives
	 * the semaphore on time
	 */

	timeout = 5;
	orig_ticks = sys_tick_get();

	task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
						test_fiber_give_timeout, (int)&sem_timeout[0],
						timeout,
						FIBER_PRIORITY, 0);

	rv = nano_task_sem_take(&sem_timeout[0], (int)(timeout + 5));
	if (!rv) {
		TC_ERROR(" *** timed out even if semaphore was given in time.\n");
		return TC_FAIL;
	}

	if (!is_timeout_in_range(orig_ticks, timeout)) {
		return TC_FAIL;
	}

	TC_PRINT("nano_task_sem_take() got sem in time, as expected\n");

	/*
	 * test nano_task_sem_take() with TICKS_NONE and the
	 * semaphore unavailable.
	 */

	if (nano_task_sem_take(&sem_timeout[0], TICKS_NONE)) {
		TC_ERROR("task with TICKS_NONE got sem, but shouldn't have\n");
		return TC_FAIL;
	}

	TC_PRINT("task with TICKS_NONE did not get sem, as expected\n");

	/*
	 * test nano_task_sem_take() with TICKS_NONE and the
	 * semaphore available.
	 */

	nano_task_sem_give(&sem_timeout[0]);
	if (!nano_task_sem_take(&sem_timeout[0], TICKS_NONE)) {
		TC_ERROR("task with TICKS_NONE did not get available sem\n");
		return TC_FAIL;
	}

	TC_PRINT("task with TICKS_NONE got available sem, as expected\n");

	/*
	 * test nano_task_sem_take() with TICKS_UNLIMITED and the
	 * semaphore available.
	 */

	TC_PRINT("Trying to take available sem with TICKS_UNLIMITED:\n"
			 " will hang the test if it fails.\n");

	nano_task_sem_give(&sem_timeout[0]);
	if (!nano_task_sem_take(&sem_timeout[0], TICKS_UNLIMITED)) {
		TC_ERROR(" *** This will never be hit!!! .\n");
		return TC_FAIL;
	}

	TC_PRINT("task with TICKS_UNLIMITED got available sem, as expected\n");

	/* test fiber with timeout of TICKS_NONE not getting empty semaphore */

	task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
						test_fiber_ticks_special_values,
						(int)&reply_packet, TICKS_NONE, FIBER_PRIORITY, 0);

	if (!nano_task_fifo_get(&timeout_order_fifo, TICKS_NONE)) {
		TC_ERROR(" *** fiber should have run and filled the fifo.\n");
		return TC_FAIL;
	}

	if (reply_packet.reply != 0) {
		TC_ERROR(" *** fiber should not have obtained the semaphore.\n");
		return TC_FAIL;
	}

	TC_PRINT("fiber with TICKS_NONE did not get sem, as expected\n");

	/* test fiber with timeout of TICKS_NONE getting full semaphore */

	nano_task_sem_give(&sem_timeout[0]);

	task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
						test_fiber_ticks_special_values,
						(int)&reply_packet, TICKS_NONE, FIBER_PRIORITY, 0);

	if (!nano_task_fifo_get(&timeout_order_fifo, TICKS_NONE)) {
		TC_ERROR(" *** fiber should have run and filled the fifo.\n");
		return TC_FAIL;
	}

	if (reply_packet.reply != 1) {
		TC_ERROR(" *** fiber should have obtained the semaphore.\n");
		return TC_FAIL;
	}

	TC_PRINT("fiber with TICKS_NONE got available sem, as expected\n");

	/* test fiber with timeout of TICKS_UNLIMITED getting full semaphore */

	nano_task_sem_give(&sem_timeout[0]);

	task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
						test_fiber_ticks_special_values,
						(int)&reply_packet, TICKS_UNLIMITED, FIBER_PRIORITY, 0);

	if (!nano_task_fifo_get(&timeout_order_fifo, TICKS_NONE)) {
		TC_ERROR(" *** fiber should have run and filled the fifo.\n");
		return TC_FAIL;
	}

	if (reply_packet.reply != 1) {
		TC_ERROR(" *** fiber should have obtained the semaphore.\n");
		return TC_FAIL;
	}

	TC_PRINT("fiber with TICKS_UNLIMITED got available sem, as expected\n");

	/* test multiple fibers pending on the same sem with different timeouts */

	test_data_size = ARRAY_SIZE(timeout_order_data);

	TC_PRINT("testing timeouts of %d fibers on same sem\n", test_data_size);

	rv = test_multiple_fibers_pending(timeout_order_data, test_data_size);
	if (rv != TC_PASS) {
		TC_ERROR(" *** fibers did not time out in the right order\n");
		return TC_FAIL;
	}

	/* test multiple fibers pending on different sems with different timeouts */

	test_data_size = ARRAY_SIZE(timeout_order_data_mult_sem);

	TC_PRINT("testing timeouts of %d fibers on different sems\n",
				test_data_size);

	rv = test_multiple_fibers_pending(timeout_order_data_mult_sem,
										test_data_size);
	if (rv != TC_PASS) {
		TC_ERROR(" *** fibers did not time out in the right order\n");
		return TC_FAIL;
	}

	/*
	 * test multiple fibers pending on same sem with different timeouts, but
	 * getting the semaphore in time, except the last one.
	 */

	test_data_size = ARRAY_SIZE(timeout_order_data);

	TC_PRINT("testing %d fibers timing out, but obtaining the sem in time\n"
				"(except the last one, which times out)\n",
				test_data_size);

	rv = test_multiple_fibers_get_sem(timeout_order_data, test_data_size);
	if (rv != TC_PASS) {
		TC_ERROR(" *** fibers did not get the sem in the right order\n");
		return TC_FAIL;
	}

	return TC_PASS;
}

/**
 *
 * @brief Entry point to semaphore tests
 *
 * This is the entry point to the semaphore tests.
 *
 * @return N/A
 */

void main(void)
{
	int     rv;       /* return value from tests */

	TC_START("Test Nanokernel Semaphores");

	initNanoObjects();

	rv = testSemTaskNoWait();
	if (rv != TC_PASS) {
		goto doneTests;
	}

	rv = testSemIsrNoWait();
	if (rv != TC_PASS) {
		goto doneTests;
	}

	semTestState = STS_INIT;

	/*
	 * Start the fiber.  The fiber will be given a higher priority than the
	 * main task.
	 */

	task_fiber_start(fiberStack, FIBER_STACKSIZE, fiberEntry,
					 0, 0, FIBER_PRIORITY, 0);

	rv = testSemWait();
	if (rv != TC_PASS) {
		goto doneTests;
	}

	rv = test_multiple_waiters();
	if (rv != TC_PASS) {
		goto doneTests;
	}

	rv = test_timeout();
	if (rv != TC_PASS) {
		goto doneTests;
	}

doneTests:
	TC_END_RESULT(rv);
	TC_END_REPORT(rv);
}
