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_wait(&testSem); /* 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_wait(&testSem); /* 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; }
int nano_task_sem_take_wait_timeout(struct nano_sem *sem, int32_t timeout_in_ticks) { int64_t cur_ticks, limit; unsigned int key; if (unlikely(TICKS_UNLIMITED == timeout_in_ticks)) { nano_task_sem_take_wait(sem); return 1; } if (unlikely(TICKS_NONE == timeout_in_ticks)) { return nano_task_sem_take(sem); } 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(sem->nsig > 0)) { sem->nsig--; irq_unlock_inline(key); return 1; } /* 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 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); } }
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_wait(&nanoFifoObj2); if (pData != pPutList2[i]) { TC_ERROR("nano_task_fifo_get_wait() 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_wait(&nanoSemObjTask); 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_wait(&nanoSemObjTask); TC_PRINT("Test Task FIFO Get\n"); /* Get all FIFOs */ while ((pData = nano_task_fifo_get(&nanoFifoObj)) != 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); }