示例#1
0
文件: lifo.c 项目: 32bitmicro/zephyr
static int do_test_multiple_waiters(void)
{
	int ii;

	/* pend all fibers one the same lifo */
	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_lifo_put(&multi_waiters, &multi_waiters_items[ii]);
	}

	/* 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_lifo_get(&multi_waiters, TICKS_NONE)) {
		TC_ERROR(" *** multi_waiters should have been empty.\n");
		return TC_FAIL;
	}

	return TC_PASS;
}
示例#2
0
文件: lifo.c 项目: 32bitmicro/zephyr
int taskLifoWaitTest(void)
{
	void *data;    /* ptr to data retrieved from LIFO */

	/* Wait on <taskWaitSem> in case fiber's print message blocked */
	nano_fiber_sem_take(&taskWaitSem, TICKS_UNLIMITED);

	/* The fiber is waiting on the LIFO.  Wake it. */
	nano_task_lifo_put(&test_lifo, &lifoItem[0]);

	/*
	 * The fiber ran, but is now blocked on the semaphore.  Add an item to the
	 * LIFO before giving the semaphore that wakes the fiber so that we can
	 * cover the path of nano_fiber_lifo_get(TICKS_UNLIMITED) not waiting on
	 * the LIFO.
	 */

	nano_task_lifo_put(&test_lifo, &lifoItem[2]);
	nano_task_sem_give(&fiberWaitSem);

	/* Check that the fiber got the correct item (lifoItem[0]) */

	if (fiberDetectedFailure) {
		TC_ERROR(" *** nano_task_lifo_put()/nano_fiber_lifo_get() failure\n");
		return TC_FAIL;
	}

	/* The LIFO is empty.  This time the task will wait for the item. */

	TC_PRINT("Task waiting on an empty LIFO\n");
	data = nano_task_lifo_get(&test_lifo, TICKS_UNLIMITED);
	if (data != (void *) &lifoItem[1]) {
		TC_ERROR(" *** nano_task_lifo_get()/nano_fiber_lifo_put() failure\n");
		return TC_FAIL;
	}

	data = nano_task_lifo_get(&test_lifo, TICKS_UNLIMITED);
	if (data != (void *) &lifoItem[3]) {
		TC_ERROR(" *** nano_task_lifo_get()/nano_fiber_lifo_put() failure\n");
		return TC_FAIL;
	}


	/* Waiting on an empty LIFO passed for both fiber and task. */

	return TC_PASS;
}
示例#3
0
void *nano_task_lifo_get_wait_timeout(struct nano_lifo *lifo,
		int32_t timeout_in_ticks)
{
	int64_t cur_ticks, limit;
	unsigned int key;
	void *data;

	if (unlikely(TICKS_UNLIMITED == timeout_in_ticks)) {
		return nano_task_lifo_get_wait(lifo);
	}

	if (unlikely(TICKS_NONE == timeout_in_ticks)) {
		return nano_task_lifo_get(lifo);
	}

	key = irq_lock_inline();
	cur_ticks = nano_tick_get();
	limit = cur_ticks + timeout_in_ticks;

	while (cur_ticks < limit) {

		/*
		 * Predict that the branch will be taken to break out of the loop.
		 * There is little cost to a misprediction since that leads to idle.
		 */

		if (likely(lifo->list)) {
			data = lifo->list;
			lifo->list = *(void **)data;
			irq_unlock_inline(key);
			return data;
		}

		/* see explanation in nano_stack.c:nano_task_stack_pop_wait() */

		nano_cpu_atomic_idle(key);

		key = irq_lock_inline();
		cur_ticks = nano_tick_get();
	}

	irq_unlock_inline(key);
	return NULL;
}
示例#4
0
文件: lifo.c 项目: 32bitmicro/zephyr
/* 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;
}
示例#5
0
文件: lifo.c 项目: 32bitmicro/zephyr
int taskLifoNonWaitTest(void)
{
	void *data;    /* ptr to data retrieved from LIFO */

	/*
	 * The fiber is presently waiting for <fiberWaitSem>.  Populate the LIFO
	 * before waking the fiber.
	 */

	TC_PRINT("Fiber to get LIFO items without waiting\n");
	nano_task_lifo_put(&test_lifo, &lifoItem[2]);
	nano_task_lifo_put(&test_lifo, &lifoItem[3]);
	nano_task_sem_give(&fiberWaitSem);    /* Wake the fiber */

	/* Check that fiber received the items correctly */
	if (fiberDetectedFailure) {
		TC_ERROR(" *** nano_task_lifo_put()/nano_fiber_lifo_get() failure\n");
		return TC_FAIL;
	}

	/* Wait for the fiber to be ready */
	nano_task_sem_take(&taskWaitSem, TICKS_UNLIMITED);

	data = nano_task_lifo_get(&test_lifo, TICKS_NONE);
	if (data != (void *) &lifoItem[1]) {
		TC_ERROR(" *** nano_task_lifo_get()/nano_fiber_lifo_put() failure\n");
		return TC_FAIL;
	}

	data = nano_task_lifo_get(&test_lifo, TICKS_NONE);
	if (data != (void *) &lifoItem[0]) {
		TC_ERROR(" *** nano_task_lifo_get()/nano_fiber_lifo_put() failure\n");
		return TC_FAIL;
	}

	data = nano_task_lifo_get(&test_lifo, TICKS_NONE);
	if (data != NULL) {
		TC_ERROR(" *** nano_task_lifo_get()/nano_fiber_lifo_put() failure\n");
		return TC_FAIL;
	}

	/*
	 * Software interrupts have been configured so that when invoked,
	 * the ISR will add an item to the LIFO.  The fiber (when unblocked)
	 * trigger software interrupts to get the items from the LIFO from
	 * within an ISR.
	 *
	 * Populate the LIFO.
	 */

	TC_PRINT("ISR to get LIFO items without waiting\n");
	isrLifoInfo.data = &lifoItem[3];
	_trigger_nano_isr_lifo_put();
	isrLifoInfo.data = &lifoItem[1];
	_trigger_nano_isr_lifo_put();

	isrLifoInfo.data = NULL;    /* Force NULL to ensure [data] changes */

	nano_task_sem_give(&fiberWaitSem);    /* Wake the fiber */

	if (fiberDetectedFailure) {
		TC_ERROR(" *** nano_isr_lifo_put()/nano_isr_lifo_get() failure\n");
		return TC_FAIL;
	}

	return TC_PASS;
}
示例#6
0
文件: lifo.c 项目: sunkaizhu/zephyr
/**
 *
 * @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;
}