Example #1
0
/* the task spins fibers that get lifo data in time, except the last one */
static int test_multiple_fibers_get_data(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_data,
							(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_lifo_put(test_data[ii].lifo, get_scratch_packet());

		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, lifo %p) as expected\n",
						data->q_order, data->timeout, data->lifo);
		} 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, lifo %p) as expected\n",
					data->q_order, data->timeout, data->lifo);
	} else {
		TC_ERROR(" *** fiber %d woke up, expected %d\n",
					data->timeout_order, ii);
		return TC_FAIL;
	}

	return TC_PASS;
}
Example #2
0
void RegressionTaskEntry(void)
{
	int  tcRC;

	nano_sem_init(&test_nano_timers_sem);

	PRINT_DATA("Starting timer tests\n");
	PRINT_LINE;

	task_fiber_start(test_nano_timers_stack, 512, test_nano_timers, 0, 0, 5, 0);

	/* Test the task_timer_alloc() API */

	TC_PRINT("Test the allocation of timers\n");
	tcRC = testLowTimerGet();
	if (tcRC != TC_PASS) {
		goto exitRtn;
	}

	TC_PRINT("Test the one shot feature of a timer\n");
	tcRC = testLowTimerOneShot();
	if (tcRC != TC_PASS) {
		goto exitRtn;
	}

	TC_PRINT("Test that a timer does not start\n");
	tcRC = testLowTimerDoesNotStart();
	if (tcRC != TC_PASS) {
		goto exitRtn;
	}

	TC_PRINT("Test the periodic feature of a timer\n");
	tcRC = testLowTimerPeriodicity();
	if (tcRC != TC_PASS) {
		goto exitRtn;
	}

	TC_PRINT("Test the stopping of a timer\n");
	tcRC = testLowTimerStop();
	if (tcRC != TC_PASS) {
		goto exitRtn;
	}

	TC_PRINT("Verifying the nanokernel timer fired\n");
	if (!nano_task_sem_take(&test_nano_timers_sem)) {
		tcRC = TC_FAIL;
		goto exitRtn;
	}

	TC_PRINT("Verifying the nanokernel timeouts worked\n");
	tcRC = task_sem_take_wait_timeout(test_nano_timeouts_sem, SECONDS(5));
	tcRC = tcRC == RC_OK ? TC_PASS : TC_FAIL;

exitRtn:
	TC_END_RESULT(tcRC);
	TC_END_REPORT(tcRC);
}
Example #3
0
/* 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_wait(&timeout_order_fifo);

		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_wait(&timeout_order_fifo);
	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;
}
Example #4
0
/**
 *
 * @brief The test main function
 *
 * @return 0 on success
 */
int nanoIntLatency(void)
{
	PRINT_FORMAT(" 1- Measure time to switch from fiber to ISR execution");
	TICK_SYNCH();
	task_fiber_start(&fiberStack[0], STACKSIZE,
					 (nano_fiber_entry_t) fiberInt, 0, 0, 6, 0);
	PRINT_FORMAT(" switching time is %lu tcs = %lu nsec",
				 timestamp, SYS_CLOCK_HW_CYCLES_TO_NS(timestamp));
	return 0;
}
Example #5
0
/**
 *
 * @brief The test main function
 *
 * @return 0 on success
 */
int nanoIntToFiber(void)
{
	PRINT_FORMAT(" 2- Measure time to switch from ISR back to interrupted"
				 " fiber");
	TICK_SYNCH();
	task_fiber_start(&fiberStack[0], STACKSIZE,
					 (nano_fiber_entry_t) fiberInt, 0, 0, 6, 0);
	if (flagVar == 1) {
		PRINT_FORMAT(" switching time is %lu tcs = %lu nsec",
					 timestamp, SYS_CLOCK_HW_CYCLES_TO_NS(timestamp));
	}
	return 0;
}
Example #6
0
void shell_init(const char *str, const struct shell_cmd *cmds)
{
	nano_fifo_init(&cmds_queue);
	nano_fifo_init(&avail_queue);

	commands = cmds;

	line_queue_init();

	prompt = str ? str : "";

	task_fiber_start(stack, STACKSIZE, shell, 0, 0, 7, 0);

	/* Register serial console handler */
	uart_register_input(&avail_queue, &cmds_queue, completion);
}
Example #7
0
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);
}
Example #8
0
File: bttester.c Project: gemtara/z
void tester_init(void)
{
	int i;

	nano_fifo_init(&cmds_queue);
	nano_fifo_init(&avail_queue);

	for (i = 0; i < CMD_QUEUED; i++) {
		nano_fifo_put(&avail_queue, &cmd_buf[i * BTP_MTU]);
	}

	task_fiber_start(stack, STACKSIZE, cmd_handler, 0, 0, 7, 0);

	uart_pipe_register(nano_fifo_get(&avail_queue, TICKS_NONE),
			   BTP_MTU, recv_cb);

	printk("BT tester initialized\n");
}
Example #9
0
void main(void)
{
	net_init();

	init_server();

	ipsum_len = strlen(lorem_ipsum);

	if (!get_context(&unicast, &multicast)) {
		PRINT("%s: Cannot get network context\n", __func__);
		return;
	}

#ifdef CONFIG_MICROKERNEL
	receiving();
#else
	task_fiber_start(&stack_receiving[0], STACKSIZE,
			(nano_fiber_entry_t)receiving, 0, 0, 7, 0);
#endif
}
Example #10
0
void main(void)
{
#ifdef CONFIG_OBJECTS_PRINTK
	printk("Using printk\n");
#endif

#if CONFIG_STATIC_ISR
	IRQ_CONNECT(IRQ_LINE, IRQ_PRIORITY, dummyIsr, NULL, 0);
#endif

#ifdef CONFIG_OBJECTS_FIBER
	/* start a trivial fiber */
	task_fiber_start(pStack, FIBER_STACK_SIZE, fiberEntry, (int) MESSAGE,
					 (int) func_array, 10, 0);
#endif

#ifdef CONFIG_OBJECTS_WHILELOOP
	while (1) {
		i++;
	}
#endif
}
Example #11
0
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)) {
			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)) {
		TC_ERROR(" *** multi_waiters should have been empty.\n");
		return TC_FAIL;
	}

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

	return TC_PASS;
}
Example #12
0
int main(void)
{
	int i;

	PRINTF(DEMO_DESCRIPTION, "fibers", "nanokernel");

	for (i = 0; i < N_PHILOSOPHERS; i++) {
		nano_sem_init(&forks[i]);
		nano_task_sem_give(&forks[i]);
	}

	/* create philosopher fibers */
	for (i = 0; i < N_PHILOSOPHERS; i++) {
		task_fiber_start(&philStack[i][0], STSIZE,
						(nano_fiber_entry_t) philEntry, 0, 0, 6, 0);
	}

	/* wait forever */
	while (1) {
		extern void nano_cpu_idle(void);
		nano_cpu_idle();
	}
}
Example #13
0
void main(void)
{
	struct nano_timer timer;
	uint32_t data[2] = {0, 0};

	task_fiber_start(&fiberStack[0], STACKSIZE,
			(nano_fiber_entry_t) fiberEntry, 0, 0, 7, 0);

	nano_sem_init(&nanoSemTask);
	nano_timer_init(&timer, data);

	while (1) {
		/* say "hello" */
		PRINT("%s: Hello Screen!\n", __FUNCTION__);

		/* wait a while, then let fiber have a turn */
		nano_task_timer_start(&timer, SLEEPTICKS);
		nano_task_timer_wait(&timer);
		nano_task_sem_give(&nanoSemFiber);

		/* now wait for fiber to let us have a turn */
		nano_task_sem_take_wait(&nanoSemTask);
	}
}
Example #14
0
void main(void)
{
	int rv = TC_PASS;

	nano_fifo_init(&fifo);

	errno = errno_values[N_FIBERS];

	printk("task, errno before starting fibers: %x\n", errno);

	for (int ii = 0; ii < N_FIBERS; ii++) {
		result[ii].pass = TC_FAIL;
	}

	for (int ii = 0; ii < N_FIBERS; ii++) {
		task_fiber_start(stacks[ii], STACK_SIZE, errno_fiber,
							ii, errno_values[ii], ii + 5, 0);
	}

	for (int ii = 0; ii < N_FIBERS; ii++) {
		struct result *p = nano_task_fifo_get(&fifo, 10);

		if (!p || !p->pass) {
			rv = TC_FAIL;
		}
	}

	printk("task, errno after running fibers:   %x\n", errno);

	if (errno != errno_values[N_FIBERS]) {
		rv = TC_FAIL;
	}

	TC_END_RESULT(rv);
	TC_END_REPORT(rv);
}
Example #15
0
/* 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_wait_timeout() with timeout */
	timeout = 10;
	orig_ticks = nano_tick_get();
	rv = nano_task_sem_take_wait_timeout(&sem_timeout[0], timeout);
	if (rv) {
		TC_ERROR(" *** timeout of %d did not time out.\n", timeout);
		return TC_FAIL;
	}
	if ((nano_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_wait_timeout with timeout of 0 */

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

	/* test nano_task_sem_take_wait_timeout with timeout > 0 */

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

	timeout = 3;
	orig_ticks = nano_tick_get();

	rv = nano_task_sem_take_wait_timeout(&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_wait_timeout timed out as expected\n");

	/*
	 * test nano_task_sem_take_wait_timeout with a timeout and fiber that gives
	 * the semaphore on time
	 */

	timeout = 5;
	orig_ticks = nano_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_wait_timeout(&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_wait_timeout got sem in time, as expected\n");

	/*
	 * test nano_task_sem_take_wait_timeout with TICKS_NONE and the
	 * semaphore unavailable.
	 */

	if (nano_task_sem_take_wait_timeout(&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_wait_timeout with TICKS_NONE and the
	 * semaphore available.
	 */

	nano_task_sem_give(&sem_timeout[0]);
	if (!nano_task_sem_take_wait_timeout(&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_wait_timeout 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_wait_timeout(&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)) {
		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)) {
		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)) {
		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;
}
Example #16
0
void main(void)
{
	int         count = 0;  /* counter */
	uint32_t    data;       /* data used to put and get from the stack queue */
	int         rc;         /* return code */

	TC_START("Test Nanokernel STACK");

	/* Initialize data */
	initData();

	/* Initialize the queues and semaphore */
	initNanoObjects();

	/* Start fiber3 */
	task_fiber_start(&fiberStack3[0], STACKSIZE, (nano_fiber_entry_t) fiber3,
					 0, 0, 7, 0);
	/*
	 * While fiber3 blocks (for one second), wait for an item to be pushed
	 * onto the stack so that it can be popped.  This will put the nanokernel
	 * into an idle state.
	 */

	rc = nano_task_stack_pop(&nanoStackObj, &data, TICKS_UNLIMITED);
	if ((rc == 0) || (data != myData[0])) {
		TC_ERROR("nano_task_stack_pop(TICKS_UNLIMITED) expected 0x%x, but got 0x%x\n",
				 myData[0], data);
		retCode = TC_FAIL;
		goto exit;
	}

	/* Put data */
	TC_PRINT("Test Task STACK Push\n");
	TC_PRINT("\nTASK STACK Put Order: ");
	for (int i=0; i<NUM_STACK_ELEMENT; i++) {
		nano_task_stack_push(&nanoStackObj, myData[i]);
		TC_PRINT(" %d,", myData[i]);
	}
	TC_PRINT("\n");

	PRINT_LINE;

	/* Start fiber */
	task_fiber_start(&fiberStack1[0], STACKSIZE,
					 (nano_fiber_entry_t) fiber1, 0, 0, 7, 0);

	if (retCode == TC_FAIL) {
		goto exit;
	}

	/*
	 * Wait for fiber1 to complete execution. (Using a semaphore gives
	 * the fiber the freedom to do blocking-type operations if it wants to.)
	 *
	 */
	nano_task_sem_take(&nanoSemObj, TICKS_UNLIMITED);
	TC_PRINT("Test Task STACK Pop\n");

	/* Get all data */
	while (nano_task_stack_pop(&nanoStackObj, &data, TICKS_NONE) != 0) {
		TC_PRINT("TASK STACK Pop: count = %d, data is %d\n", count, data);
		if ((count >= NUM_STACK_ELEMENT) || (data != myData[count])) {
			TCERR1(count);
			retCode = TC_FAIL;
			goto exit;
		}
		count++;
	}

	/* Test Task Stack Pop Wait interfaces*/
	testTaskStackPopW();

	if (retCode == TC_FAIL) {
		goto exit;
	}

	PRINT_LINE;

	/* Test ISR interfaces */
	testIsrStackFromTask();
	PRINT_LINE;

exit:
	TC_END_RESULT(retCode);
	TC_END_REPORT(retCode);
}
Example #17
0
int stack_test(void)
{
	uint32_t t;
	int i = 0;
	int return_value = 0;

	/* test get wait & put fiber functions */
	fprintf(output_file, sz_test_case_fmt,
			"Stack #1");
	fprintf(output_file, sz_description,
			"\n\tnano_stack_init"
			"\n\tnano_fiber_stack_pop_wait"
			"\n\tnano_fiber_stack_push");
	printf(sz_test_start_fmt);

	stack_test_init();

	t = BENCH_START();

	task_fiber_start(fiber_stack1, STACK_SIZE, stack_fiber1, 0,
					 NUMBER_OF_LOOPS, 3, 0);
	task_fiber_start(fiber_stack2, STACK_SIZE, stack_fiber2, (int) &i,
					 NUMBER_OF_LOOPS, 3, 0);

	t = TIME_STAMP_DELTA_GET(t);

	return_value += check_result(i, t);

	/* test get/yield & put fiber functions */
	fprintf(output_file, sz_test_case_fmt,
			"Stack #2");
	fprintf(output_file, sz_description,
			"\n\tnano_stack_init"
			"\n\tnano_fiber_stack_pop_wait"
			"\n\tnano_fiber_stack_pop"
			"\n\tnano_fiber_stack_push"
			"\n\tfiber_yield");
	printf(sz_test_start_fmt);

	stack_test_init();

	t = BENCH_START();

	i = 0;
	task_fiber_start(fiber_stack1, STACK_SIZE, stack_fiber1, 0,
					 NUMBER_OF_LOOPS, 3, 0);
	task_fiber_start(fiber_stack2, STACK_SIZE, stack_fiber3, (int) &i,
					 NUMBER_OF_LOOPS, 3, 0);

	t = TIME_STAMP_DELTA_GET(t);

	return_value += check_result(i, t);

	/* test get wait & put fiber/task functions */
	fprintf(output_file, sz_test_case_fmt,
			"Stack #3");
	fprintf(output_file, sz_description,
			"\n\tnano_stack_init"
			"\n\tnano_fiber_stack_pop_wait"
			"\n\tnano_fiber_stack_push"
			"\n\tnano_task_stack_pop_wait"
			"\n\tnano_task_stack_push");
	printf(sz_test_start_fmt);

	stack_test_init();

	t = BENCH_START();

	task_fiber_start(fiber_stack1, STACK_SIZE, stack_fiber1, 0,
					 NUMBER_OF_LOOPS, 3, 0);
	for (i = 0; i < NUMBER_OF_LOOPS / 2; i++) {
		uint32_t data;
		data = 2 * i;
		nano_task_stack_push(&nano_stack_1, data);
		data = 2 * i + 1;
		nano_task_stack_push(&nano_stack_1, data);

		data = nano_task_stack_pop_wait(&nano_stack_2);
		if (data != 2 * i + 1) {
			break;
		}
		data = nano_task_stack_pop_wait(&nano_stack_2);
		if (data != 2 * i) {
			break;
		}
	}

	t = TIME_STAMP_DELTA_GET(t);

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

	return return_value;
}
Example #18
0
/**
 *
 * @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;

	nano_fifo_init(&nanoFifo_sync);

	/* test get wait & put fiber functions */
	fprintf(output_file, sz_test_case_fmt,
			"LIFO #1");
	fprintf(output_file, sz_description,
			"\n\tnano_lifo_init"
			"\n\tnano_fiber_lifo_get(TICKS_UNLIMITED)"
			"\n\tnano_fiber_lifo_put");
	printf(sz_test_start_fmt);

	lifo_test_init();

	t = BENCH_START();

	task_fiber_start(fiber_stack1, STACK_SIZE, lifo_fiber1, 0,
					 NUMBER_OF_LOOPS, 3, 0);
	task_fiber_start(fiber_stack2, STACK_SIZE, lifo_fiber2, (int) &i,
					 NUMBER_OF_LOOPS, 3, 0);

	t = TIME_STAMP_DELTA_GET(t);

	return_value += check_result(i, t);

	/* fibers have done their job, they can stop now safely: */
	for (j = 0; j < 2; j++) {
		nano_task_fifo_put(&nanoFifo_sync, (void *) element);
	}

	/* test get/yield & put fiber functions */
	fprintf(output_file, sz_test_case_fmt,
			"LIFO #2");
	fprintf(output_file, sz_description,
			"\n\tnano_lifo_init"
			"\n\tnano_fiber_lifo_get(TICKS_UNLIMITED)"
			"\n\tnano_fiber_lifo_get(TICKS_NONE)"
			"\n\tnano_fiber_lifo_put"
			"\n\tfiber_yield");
	printf(sz_test_start_fmt);

	lifo_test_init();

	t = BENCH_START();

	i = 0;
	task_fiber_start(fiber_stack1, STACK_SIZE, lifo_fiber1, 0,
					 NUMBER_OF_LOOPS, 3, 0);
	task_fiber_start(fiber_stack2, STACK_SIZE, lifo_fiber3, (int) &i,
					 NUMBER_OF_LOOPS, 3, 0);

	t = TIME_STAMP_DELTA_GET(t);

	return_value += check_result(i, t);

	/* fibers have done their job, they can stop now safely: */
	for (j = 0; j < 2; j++) {
		nano_task_fifo_put(&nanoFifo_sync, (void *) element);
	}

	/* test get wait & put fiber/task functions */
	fprintf(output_file, sz_test_case_fmt,
			"LIFO #3");
	fprintf(output_file, sz_description,
			"\n\tnano_lifo_init"
			"\n\tnano_fiber_lifo_get(TICKS_UNLIMITED)"
			"\n\tnano_fiber_lifo_put"
			"\n\tnano_task_lifo_get(TICKS_UNLIMITED)"
			"\n\tnano_task_lifo_put");
	printf(sz_test_start_fmt);

	lifo_test_init();

	t = BENCH_START();

	task_fiber_start(fiber_stack1, STACK_SIZE, lifo_fiber1, 0,
					 NUMBER_OF_LOOPS, 3, 0);
	for (i = 0; i < NUMBER_OF_LOOPS / 2; i++) {
		int element[2];
		int *pelement;

		element[1] = 2 * i;
		nano_task_lifo_put(&nanoLifo1, element);
		element[1] = 2 * i + 1;
		nano_task_lifo_put(&nanoLifo1, element);

		pelement = (int *)nano_task_lifo_get(&nanoLifo2,
						     TICKS_UNLIMITED);
		if (pelement[1] != 2 * i + 1) {
			break;
		}
		pelement = (int *)nano_task_lifo_get(&nanoLifo2,
						     TICKS_UNLIMITED);
		if (pelement[1] != 2 * i) {
			break;
		}
	}

	t = TIME_STAMP_DELTA_GET(t);

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

	/* fibers have done their job, they can stop now safely: */
	for (j = 0; j < 2; j++) {
		nano_task_fifo_put(&nanoFifo_sync, (void *) element);
	}

	return return_value;
}
Example #19
0
void main(void)
{
	int           rv;       /* return value from tests */

	TC_START("Test Nanokernel CPU and thread routines");

	TC_PRINT("Initializing nanokernel objects\n");
	rv = initNanoObjects();
	if (rv != TC_PASS) {
		goto doneTests;
	}

	TC_PRINT("Testing nano_cpu_idle()\n");
	rv = nano_cpu_idleTest();
	if (rv != TC_PASS) {
		goto doneTests;
	}

	TC_PRINT("Testing interrupt locking and unlocking\n");
	rv = nanoCpuDisableInterruptsTest(irq_lockWrapper,
									  irq_unlockWrapper, -1);
	if (rv != TC_PASS) {
		goto doneTests;
	}


/*
 * The Cortex-M3/M4 use the SYSTICK exception for the system timer, which is
 * not considered an IRQ by the irq_enable/Disable APIs.
 */
#if !defined(CONFIG_CPU_CORTEX_M3_M4)
	/* Disable interrupts coming from the timer. */

	TC_PRINT("Testing irq_disable() and irq_enable()\n");
	rv = nanoCpuDisableInterruptsTest(irq_disableWrapper,
									  irq_enableWrapper, TICK_IRQ);
	if (rv != TC_PASS) {
		goto doneTests;
	}
#endif

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

	TC_PRINT("Spawning a fiber from a task\n");
	fiberEvidence = 0;
	task_fiber_start(fiberStack1, FIBER_STACKSIZE, fiberEntry,
					 (int) sys_thread_self_get(), 0, FIBER_PRIORITY, 0);

	if (fiberEvidence != 1) {
		rv = TC_FAIL;
		TC_ERROR("  - fiber did not execute as expected!\n");
		goto doneTests;
	}

	/*
	 * The fiber ran, now wake it so it can test sys_thread_self_get and
	 * sys_execution_context_type_get.
	 */
	TC_PRINT("Fiber to test sys_thread_self_get() and sys_execution_context_type_get\n");
	nano_task_sem_give(&wakeFiber);

	if (fiberDetectedError != 0) {
		rv = TC_FAIL;
		TC_ERROR("  - failure detected in fiber; fiberDetectedError = %d\n",
				 fiberDetectedError);
		goto doneTests;
	}

	TC_PRINT("Fiber to test fiber_yield()\n");
	nano_task_sem_give(&wakeFiber);

	if (fiberDetectedError != 0) {
		rv = TC_FAIL;
		TC_ERROR("  - failure detected in fiber; fiberDetectedError = %d\n",
				 fiberDetectedError);
		goto doneTests;
	}

	nano_task_sem_give(&wakeFiber);

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

/* Cortex-M3/M4 does not implement connecting non-IRQ exception handlers */
#if !defined(CONFIG_CPU_CORTEX_M3_M4)
	/*
	 * Test divide by zero exception handler.
	 *
	 * WARNING: This code has been very carefully crafted so that it does
	 * what it is supposed to. Both "error" and "excHandlerExecuted" must be
	 * volatile to prevent the compiler from issuing a "divide by zero"
	 * warning (since otherwise in knows "excHandlerExecuted" is zero),
	 * and to ensure the compiler issues the two byte "idiv" instruction
	 * that the exception handler is designed to deal with.
	 */

	volatile int error;    /* used to create a divide by zero error */
	TC_PRINT("Verifying exception handler installed\n");
	excHandlerExecuted = 0;
	error = error / excHandlerExecuted;
	TC_PRINT("excHandlerExecuted: %d\n", excHandlerExecuted);

	rv = (excHandlerExecuted == 1) ? TC_PASS : TC_FAIL;
#endif

doneTests:
	TC_END_RESULT(rv);
	TC_END_REPORT(rv);
}
Example #20
0
/* the timeout test entry point */
static int test_timeout(void)
{
	int64_t orig_ticks;
	int32_t timeout;
	int rv;
	void *packet, *scratch_packet;
	int test_data_size;
	int ii;
	struct reply_packet reply_packet;

	nano_lifo_init(&lifo_timeout[0]);
	nano_lifo_init(&lifo_timeout[1]);
	nano_fifo_init(&timeout_order_fifo);
	nano_fifo_init(&scratch_q_packets_fifo);

	for (ii = 0; ii < NUM_SCRATCH_Q_PACKETS; ii++) {
		scratch_q_packets[ii].data_if_needed = (void *)ii;
		nano_task_fifo_put(&scratch_q_packets_fifo,
							&scratch_q_packets[ii]);
	}

	/* test nano_task_lifo_get() with timeout */
	timeout = 10;
	orig_ticks = sys_tick_get();
	packet = nano_task_lifo_get(&lifo_timeout[0], timeout);
	if (packet) {
		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_lifo_get() with timeout of 0 */

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

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

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

	timeout = 3;
	orig_ticks = sys_tick_get();

	packet = nano_task_lifo_get(&lifo_timeout[0], timeout);

	if (packet) {
		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_lifo_get() timed out as expected\n");

	/*
	 * test nano_task_lifo_get() with a timeout and fiber that puts
	 * data on the lifo on time
	 */

	timeout = 5;
	orig_ticks = sys_tick_get();

	task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
						test_fiber_put_timeout, (int)&lifo_timeout[0],
						timeout,
						FIBER_PRIORITY, 0);

	packet = nano_task_lifo_get(&lifo_timeout[0],
												(int)(timeout + 5));
	if (!packet) {
		TC_ERROR(" *** data put in time did not return valid pointer.\n");
		return TC_FAIL;
	}

	put_scratch_packet(packet);

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

	TC_PRINT("nano_task_lifo_get() got lifo in time, as expected\n");

	/*
	 * test nano_task_lifo_get() with TICKS_NONE and no data
	 * unavailable.
	 */

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

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

	/*
	 * test nano_task_lifo_get() with TICKS_NONE and some data
	 * available.
	 */

	scratch_packet = get_scratch_packet();
	nano_task_lifo_put(&lifo_timeout[0], scratch_packet);
	if (!nano_task_lifo_get(&lifo_timeout[0], TICKS_NONE)) {
		TC_ERROR("task with TICKS_NONE did not get available data\n");
		return TC_FAIL;
	}
	put_scratch_packet(scratch_packet);

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

	/*
	 * test nano_task_lifo_get() with TICKS_UNLIMITED and the
	 * data available.
	 */

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

	scratch_packet = get_scratch_packet();
	nano_task_lifo_put(&lifo_timeout[0], scratch_packet);
	if (!nano_task_lifo_get(&lifo_timeout[0], TICKS_UNLIMITED)) {
		TC_ERROR(" *** This will never be hit!!! .\n");
		return TC_FAIL;
	}
	put_scratch_packet(scratch_packet);

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

	/* test fiber with timeout of TICKS_NONE not getting data on empty lifo */

	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 data.\n");
		return TC_FAIL;
	}

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

	/* test fiber with timeout of TICKS_NONE getting data when available */

	scratch_packet = get_scratch_packet();
	nano_task_lifo_put(&lifo_timeout[0], scratch_packet);
	task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
						test_fiber_ticks_special_values,
						(int)&reply_packet, TICKS_NONE, FIBER_PRIORITY, 0);
	put_scratch_packet(scratch_packet);

	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 data.\n");
		return TC_FAIL;
	}

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

	/* test fiber with TICKS_UNLIMITED timeout getting data when availalble */

	scratch_packet = get_scratch_packet();
	nano_task_lifo_put(&lifo_timeout[0], scratch_packet);
	task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
						test_fiber_ticks_special_values,
						(int)&reply_packet, TICKS_UNLIMITED, FIBER_PRIORITY, 0);
	put_scratch_packet(scratch_packet);

	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 data.\n");
		return TC_FAIL;
	}

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

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

	test_data_size = ARRAY_SIZE(timeout_order_data);

	TC_PRINT("testing timeouts of %d fibers on same lifo\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 mult. fibers pending on different lifos with different timeouts */

	test_data_size = ARRAY_SIZE(timeout_order_data_mult_lifo);

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

	rv = test_multiple_fibers_pending(timeout_order_data_mult_lifo,
										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 lifo with different timeouts, but
	 * getting the data in time, except the last one.
	 */

	test_data_size = ARRAY_SIZE(timeout_order_data);

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

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

	return TC_PASS;
}
Example #21
0
void main(void)
{
	void   *pData;      /* pointer to FIFO object get from the queue */
	int     count = 0;  /* counter */

	TC_START("Test Nanokernel FIFO");

	/* Initialize the FIFO queues and semaphore */
	initNanoObjects();

	/* Create and start the three (3) fibers. */

	task_fiber_start(&fiberStack1[0], FIBER_STACKSIZE, (nano_fiber_entry_t) fiber1,
					 0, 0, 7, 0);

	task_fiber_start(&fiberStack2[0], FIBER_STACKSIZE, (nano_fiber_entry_t) fiber2,
					 0, 0, 7, 0);

	task_fiber_start(&fiberStack3[0], FIBER_STACKSIZE, (nano_fiber_entry_t) fiber3,
					 0, 0, 7, 0);

	/*
	 * The three fibers have each blocked on a different semaphore.  Giving
	 * the semaphore nanoSemObjX will unblock fiberX (where X = {1, 2, 3}).
	 *
	 * Activate fibers #1 and #2.  They will each block on nanoFifoObj.
	 */

	nano_task_sem_give(&nanoSemObj1);
	nano_task_sem_give(&nanoSemObj2);

	/* Put two items into <nanoFifoObj> to unblock fibers #1 and #2. */
	nano_task_fifo_put(&nanoFifoObj, pPutList1[0]);    /* Wake fiber1 */
	nano_task_fifo_put(&nanoFifoObj, pPutList1[1]);    /* Wake fiber2 */

	/* Activate fiber #3 */
	nano_task_sem_give(&nanoSemObj3);

	/*
	 * All three fibers should be blocked on their semaphores.  Put data into
	 * <nanoFifoObj2>.  Fiber #3 will read it after it is reactivated.
	 */

	nano_task_fifo_put(&nanoFifoObj2, pPutList2[0]);
	nano_task_sem_give(&nanoSemObj3);    /* Reactivate fiber #3 */

	for (int i = 0; i < 4; i++) {
		pData = nano_task_fifo_get(&nanoFifoObj2, TICKS_UNLIMITED);
		if (pData != pPutList2[i]) {
			TC_ERROR("nano_task_fifo_get() expected 0x%x, got 0x%x\n",
					 pPutList2[i], pData);
			goto exit;
		}
	}

	/* Add items to <nanoFifoObj> for fiber #2 */
	for (int i = 0; i < 4; i++) {
		nano_task_fifo_put(&nanoFifoObj, pPutList1[i]);
	}

	nano_task_sem_give(&nanoSemObj2);   /* Activate fiber #2 */

	/* Wait for fibers to finish */
	nano_task_sem_take(&nanoSemObjTask, TICKS_UNLIMITED);

	if (retCode == TC_FAIL) {
		goto exit;
	}

	/*
	 * Entries in the FIFO queue have to be unique.
	 * Put data to queue.
	 */

	TC_PRINT("Test Task FIFO Put\n");
	TC_PRINT("\nTASK FIFO Put Order: ");
	for (int i = 0; i < NUM_FIFO_ELEMENT; i++) {
		nano_task_fifo_put(&nanoFifoObj, pPutList1[i]);
		TC_PRINT(" %p,", pPutList1[i]);
	}
	TC_PRINT("\n");

	PRINT_LINE;

	nano_task_sem_give(&nanoSemObj1);      /* Activate fiber1 */

	if (retCode == TC_FAIL) {
		goto exit;
	}

	/*
	 * Wait for fiber1 to complete execution. (Using a semaphore gives
	 * the fiber the freedom to do blocking-type operations if it wants to.)
	 */
	nano_task_sem_take(&nanoSemObjTask, TICKS_UNLIMITED);

	TC_PRINT("Test Task FIFO Get\n");

	/* Get all FIFOs */
	while ((pData = nano_task_fifo_get(&nanoFifoObj, TICKS_NONE)) != NULL) {
		TC_PRINT("TASK FIFO Get: count = %d, ptr is %p\n", count, pData);
		if ((count >= NUM_FIFO_ELEMENT) || (pData != pPutList2[count])) {
			TCERR1(count);
			retCode = TC_FAIL;
			goto exit;
		}
		count++;
	}

	/* Test FIFO Get Wait interfaces*/
	testTaskFifoGetW();
	PRINT_LINE;

	testIsrFifoFromTask();
	PRINT_LINE;

	/* test timeouts */
	if (test_fifo_timeout() != TC_PASS) {
		retCode = TC_FAIL;
		goto exit;
	}
	PRINT_LINE;

exit:
	TC_END_RESULT(retCode);
	TC_END_REPORT(retCode);
}
Example #22
0
void testFiberInit(void)
{
	nano_sem_init(&fiberSem);
	task_fiber_start(fiberStack, FIBER_STACK_SIZE, (nano_fiber_entry_t)testFiberEntry,
		    0, 0, FIBER_PRIORITY, 0);
}
Example #23
0
static int test_timeout(void)
{
	int32_t timeout;
	int rv;
	int ii;
	struct timeout_order_data *data;

/*
 * sys_thread_busy_wait() is currently unsupported for ARM
 */

#ifndef CONFIG_ARM

	/* test sys_thread_busy_wait() */

	TC_PRINT("Testing sys_thread_busy_wait()\n");
	timeout = 2;
	task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
						test_fiber_busy_wait, (int)timeout, 0,
						FIBER_PRIORITY, 0);

	rv = nano_task_sem_take(&reply_timeout, timeout + 2);
	if (!rv) {
		rv = TC_FAIL;
		TC_ERROR(" *** task timed out waiting for sys_thread_busy_wait()\n");
		return TC_FAIL;
	}

#endif /* CONFIG_ARM */

	/* test fiber_sleep() */

	TC_PRINT("Testing fiber_sleep()\n");
	timeout = 5;
	task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
						test_fiber_sleep, (int)timeout, 0,
						FIBER_PRIORITY, 0);

	rv = nano_task_sem_take(&reply_timeout, timeout + 5);
	if (!rv) {
		rv = TC_FAIL;
		TC_ERROR(" *** task timed out waiting for fiber on fiber_sleep().\n");
		return TC_FAIL;
	}

	/* test fiber_delayed_start() without cancellation */

	TC_PRINT("Testing fiber_delayed_start() without cancellation\n");

	for (ii = 0; ii < NUM_TIMEOUT_FIBERS; ii++) {
		(void)task_fiber_delayed_start(timeout_stacks[ii], FIBER_STACKSIZE,
										delayed_fiber, ii, 0, 5, 0,
										timeout_order_data[ii].timeout);
	}
	for (ii = 0; ii < NUM_TIMEOUT_FIBERS; ii++) {

		data = nano_task_fifo_get(&timeout_order_fifo, TIMEOUT_TWO_INTERVALS);

		if (!data) {
			TC_ERROR(" *** timeout while waiting for delayed fiber\n");
			return TC_FAIL;
		}

		if (data->timeout_order != ii) {
			TC_ERROR(" *** wrong delayed fiber ran (got %d, expected %d)\n",
						data->timeout_order, ii);
			return TC_FAIL;
		}

		TC_PRINT(" got fiber (q order: %d, t/o: %d) as expected\n",
					data->q_order, data->timeout);
	}

	/* ensure no more fibers fire */

	data = nano_task_fifo_get(&timeout_order_fifo, TIMEOUT_TWO_INTERVALS);

	if (data) {
		TC_ERROR(" *** got something on the fifo, but shouldn't have...\n");
		return TC_FAIL;
	}

	/* test fiber_delayed_start() with cancellation */

	TC_PRINT("Testing fiber_delayed_start() with cancellations\n");

	int cancellations[] = {0, 3, 4, 6};
	int num_cancellations = ARRAY_SIZE(cancellations);
	int next_cancellation = 0;

	void *delayed_fibers[NUM_TIMEOUT_FIBERS];

	for (ii = 0; ii < NUM_TIMEOUT_FIBERS; ii++) {
		delayed_fibers[ii] =
			task_fiber_delayed_start(timeout_stacks[ii], FIBER_STACKSIZE,
										delayed_fiber, ii, 0, 5, 0,
										timeout_order_data[ii].timeout);
	}

	for (ii = 0; ii < NUM_TIMEOUT_FIBERS; ii++) {
		int jj;

		if (ii == cancellations[next_cancellation]) {
			TC_PRINT(" cancelling [q order: %d, t/o: %d, t/o order: %d]\n",
						timeout_order_data[ii].q_order,
						timeout_order_data[ii].timeout, ii);
			for (jj = 0; jj < NUM_TIMEOUT_FIBERS; jj++) {
				if (timeout_order_data[jj].timeout_order == ii) {
					break;
				}
			}
			task_fiber_delayed_start_cancel(delayed_fibers[jj]);
			++next_cancellation;
			continue;
		}

		data = nano_task_fifo_get(&timeout_order_fifo, TIMEOUT_TEN_INTERVALS);

		if (!data) {
			TC_ERROR(" *** timeout while waiting for delayed fiber\n");
			return TC_FAIL;
		}

		if (data->timeout_order != ii) {
			TC_ERROR(" *** wrong delayed fiber ran (got %d, expected %d)\n",
						data->timeout_order, ii);
			return TC_FAIL;
		}

		TC_PRINT(" got (q order: %d, t/o: %d, t/o order %d) as expected\n",
					data->q_order, data->timeout);
	}

	if (num_cancellations != next_cancellation) {
		TC_ERROR(" *** wrong number of cancellations (expected %d, got %d\n",
					num_cancellations, next_cancellation);
		return TC_FAIL;
	}

	/* ensure no more fibers fire */

	data = nano_task_fifo_get(&timeout_order_fifo, TIMEOUT_TWO_INTERVALS);

	if (data) {
		TC_ERROR(" *** got something on the fifo, but shouldn't have...\n");
		return TC_FAIL;
	}

	return TC_PASS;
}