void RegressionTask(void) { uint32_t nCalls = 0; int status; TC_START("Test Microkernel Critical Section API\n"); task_sem_give(ALT_SEM); /* Activate AlternateTask() */ nCalls = criticalLoop(nCalls); /* Wait for AlternateTask() to complete */ status = task_sem_take_wait_timeout(REGRESS_SEM, TEST_TIMEOUT); if (status != RC_OK) { TC_ERROR("Timed out waiting for REGRESS_SEM\n"); goto errorReturn; } if (criticalVar != nCalls + altTaskIterations) { TC_ERROR("Unexpected value for <criticalVar>. Expected %d, got %d\n", nCalls + altTaskIterations, criticalVar); goto errorReturn; } TC_PRINT("Obtained expected <criticalVar> value of %u\n", criticalVar); TC_PRINT("Enabling time slicing ...\n"); sys_scheduler_time_slice_set(1, 10); task_sem_give(ALT_SEM); /* Re-activate AlternateTask() */ nCalls = criticalLoop(nCalls); /* Wait for AlternateTask() to finish */ status = task_sem_take_wait_timeout(REGRESS_SEM, TEST_TIMEOUT); if (status != RC_OK) { TC_ERROR("Timed out waiting for REGRESS_SEM\n"); goto errorReturn; } if (criticalVar != nCalls + altTaskIterations) { TC_ERROR("Unexpected value for <criticalVar>. Expected %d, got %d\n", nCalls + altTaskIterations, criticalVar); goto errorReturn; } TC_PRINT("Obtained expected <criticalVar> value of %u\n", criticalVar); TC_END_RESULT(TC_PASS); TC_END_REPORT(TC_PASS); return; errorReturn: TC_END_RESULT(TC_FAIL); TC_END_REPORT(TC_FAIL); }
void HelperTask(void) { void *ptr[NUMBLOCKS]; /* Pointer to memory block */ /* Wait for part 1 to complete */ task_sem_take(SEM_REGRESSDONE, TICKS_UNLIMITED); /* Part 2 of test */ TC_PRINT("Starts %s\n", __func__); /* Test task_mem_map_alloc */ tcRC = testMapGetAllBlocks(ptr); if (tcRC == TC_FAIL) { TC_ERROR("Failed testMapGetAllBlocks function\n"); goto exitTest1; /* terminate test */ } task_sem_give(SEM_HELPERDONE); /* Indicate part 2 is complete */ /* Wait for part 3 to complete */ task_sem_take(SEM_REGRESSDONE, TICKS_UNLIMITED); /* * Part 4 of test. * Free the first memory block. RegressionTask is currently blocked * waiting (with a timeout) for a memory block. Freeing the memory * block will unblock RegressionTask. */ TC_PRINT("%s: About to free a memory block\n", __func__); task_mem_map_free(MAP_LgBlks, &ptr[0]); task_sem_give(SEM_HELPERDONE); /* Part 5 of test */ task_sem_take(SEM_REGRESSDONE, TICKS_UNLIMITED); TC_PRINT("%s: About to free another memory block\n", __func__); task_mem_map_free(MAP_LgBlks, &ptr[1]); /* * Free all the other blocks. The first 2 blocks are freed by this task */ for (int i = 2; i < NUMBLOCKS; i++) { task_mem_map_free(MAP_LgBlks, &ptr[i]); } TC_PRINT("%s: freed all blocks allocated by this task\n", __func__); exitTest1: TC_END_RESULT(tcRC); task_sem_give(SEM_HELPERDONE); } /* HelperTask */
void AlternateTask(void) { task_sem_take_wait(ALT_SEM); /* Wait to be activated */ altTaskIterations = criticalLoop(altTaskIterations); task_sem_give(REGRESS_SEM); task_sem_take_wait(ALT_SEM); /* Wait to be re-activated */ altTaskIterations = criticalLoop(altTaskIterations); task_sem_give(REGRESS_SEM); }
int HighPriTask(void) { int status; /* Wait until task is activated */ status = task_sem_take(hpSem, TICKS_UNLIMITED); if (status != RC_OK) { TC_ERROR("%s priority task failed to wait on %s: %d\n", "High", "HIGH_PRI_SEM", status); return TC_FAIL; } /* Wait on a semaphore along with other tasks */ status = task_sem_take(manyBlockSem, TICKS_UNLIMITED); if (status != RC_OK) { TC_ERROR("%s priority task failed to wait on %s: %d\n", "High", "MANY_BLOCKED_SEM", status); return TC_FAIL; } /* Inform Regression test HP task is no longer blocked on MANY_BLOCKED_SEM*/ task_sem_give(blockHpSem); return TC_PASS; }
/** * Signal g_TimerSem to wake-up timer_task. * */ static void signal_timer_task(void) { #ifdef CONFIG_NANOKERNEL nano_sem_give(&g_TimerSem); #else T_EXEC_LEVEL execLvl; execLvl = _getExecLevel(); /* call the nanoK service that corresponds to the current execution level */ switch (execLvl) { case E_EXEC_LVL_ISR: isr_sem_give(g_TimerSem); break; case E_EXEC_LVL_FIBER: fiber_sem_give(g_TimerSem); break; case E_EXEC_LVL_TASK: task_sem_give(g_TimerSem); break; default: /* will not do that from unknown context */ panic(E_OS_ERR_NOT_SUPPORTED); break; } #endif }
int pipeGetWaitTest(void) { int rv; /* return code from pipeGetWaitTestWork() */ int bytesRead; /* # of bytes read from task_pipe_get_waitait() */ task_sem_give(altSem); /* Wake AlternateTask */ rv = pipeGetWaitTestWork(wait_all_N, ARRAY_SIZE(wait_all_N)); if (rv != TC_PASS) { TC_ERROR("Failed on _ALL_N test\n"); return TC_FAIL; } rv = pipeGetWaitTestWork(wait_one_to_N, ARRAY_SIZE(wait_one_to_N)); if (rv != TC_PASS) { TC_ERROR("Failed on _1_TO_N test\n"); return TC_FAIL; } rv = task_pipe_get_wait(pipeId, rxBuffer, PIPE_SIZE, &bytesRead, _0_TO_N); if (rv != RC_FAIL) { TC_ERROR("Expected return code of %d, not %d\n", RC_FAIL, rv); return TC_FAIL; } return TC_PASS; }
/* * * @param taskname task identification string * @param mySem task's own semaphore * @param otherSem other task's semaphore * */ void helloLoop(const char *taskname, ksem_t mySem, ksem_t otherSem) { while (1) { task_sem_take(mySem, TICKS_UNLIMITED);; if (gpio) { if (mySem == TASKASEM) { gpio_pin_write(gpio, 6, 1); gpio_pin_write(gpio, 8, 0); gpio_pin_write(gpio_sus, 5, 0); } else if (mySem == TASKBSEM) { gpio_pin_write(gpio, 8, 1); gpio_pin_write(gpio, 6, 0); gpio_pin_write(gpio_sus, 5, 1); } } /* say "hello" */ PRINT("%s: Hello World!\n", taskname); /* wait a while, then let other task have a turn */ task_sleep(SLEEPTICKS); task_sem_give(otherSem); } }
void taskA(void) { /* taskA gives its own semaphore, allowing it to say hello right away */ task_sem_give(TASKASEM); /* invoke routine that allows task to ping-pong hello messages with taskB */ helloLoop(__func__, TASKASEM, TASKBSEM); }
void test_nano_timeouts(void) { if (test_fifo_timeout() == TC_PASS) { task_sem_give(test_nano_timeouts_sem); } /* on failure, don't give semaphore, main test will time out */ }
int pipePutTimeoutHelper(void) { int i; /* loop counter */ int rv; /* return value from task_pipe_get_wait_timeout() */ int bytesRead; /* # of bytes read from task_pipe_get_wait_timeout() */ (void)task_sem_take_wait(altSem); /* Wait until test is ready */ /* 1. task_pipe_get_wait_timeout() will force a context switch to RegressionTask() */ rv = task_pipe_get_wait_timeout(pipeId, rxBuffer, PIPE_SIZE, &bytesRead, _ALL_N, ONE_SECOND); if ((rv != RC_OK) || (bytesRead != PIPE_SIZE)) { TC_ERROR("Expected return code %d, not %d\n" "Expected %d bytes to be read, not %d\n", RC_OK, rv, PIPE_SIZE, bytesRead); return TC_FAIL; } /* 2. task_pipe_get_wait_timeout() will force a context switch to RegressionTask(). */ rv = task_pipe_get_wait_timeout(pipeId, rxBuffer, PIPE_SIZE, &bytesRead, _1_TO_N, ONE_SECOND); if ((rv != RC_OK) || (bytesRead != PIPE_SIZE)) { TC_ERROR("Expected return code %d, not %d\n" "Expected %d bytes to be read, not %d\n", RC_OK, rv, PIPE_SIZE, bytesRead); return TC_FAIL; } /* * Before emptying the pipe, check that task_pipe_get_wait_timeout() fails when * using the _0_TO_N option. */ rv = task_pipe_get_wait_timeout(pipeId, rxBuffer, PIPE_SIZE / 2, &bytesRead, _0_TO_N, ONE_SECOND); if (rv != RC_FAIL) { TC_ERROR("Expected return code %d, not %d\n", RC_FAIL, rv); return TC_FAIL; } /* 3. Empty the pipe in two reads */ for (i = 0; i < 2; i++) { rv = task_pipe_get(pipeId, rxBuffer, PIPE_SIZE / 2, &bytesRead, _0_TO_N); if ((rv != RC_OK) || (bytesRead != PIPE_SIZE / 2)) { TC_ERROR("Expected return code %d, not %d\n" "Expected %d bytes to be read, not %d\n", RC_OK, rv, PIPE_SIZE / 2, bytesRead); return TC_FAIL; } } task_sem_give(regSem); return TC_PASS; }
void taskA(void) { int rc1; int rc2; gpio = device_get_binding(CONFIG_GPIO_PCAL9535A_1_DEV_NAME); gpio_sus = device_get_binding(CONFIG_GPIO_SCH_1_DEV_NAME); i2c = device_get_binding(CONFIG_GPIO_PCAL9535A_1_I2C_MASTER_DEV_NAME); pinmux = device_get_binding(PINMUX_NAME); if (!i2c) { PRINT("I2C not found!!\n"); } else { rc1 = i2c_configure(i2c, (I2C_SPEED_FAST << 1) | I2C_MODE_MASTER); if (rc1 != DEV_OK) { PRINT("I2C configuration error: %d\n", rc1); } } if (!gpio) { PRINT("GPIO not found!!\n"); } else { rc1 = gpio_pin_configure(gpio, 6, GPIO_DIR_OUT); rc2 = gpio_pin_configure(gpio, 8, GPIO_DIR_OUT); if (rc1 != DEV_OK || rc2 != DEV_OK) { PRINT("GPIO config error %d, %d!!\n", rc1, rc2); } } if (!gpio_sus) { PRINT("Legacy GPIO not found!!\n"); } else { rc1 = gpio_pin_configure(gpio_sus, 5, GPIO_DIR_OUT); if (rc1 != DEV_OK) { PRINT("Legacy GPIO config error %d!!\n", rc1); } } if (!pinmux) { PRINT("Pinmux device not found!\n"); } else { /* * By default pin D13 (pin 5 on Legacy GPIO_SUS * is configured for input. To blink it, it needs to * be configured for output */ rc1 = pinmux_pin_set(pinmux, 13, PINMUX_FUNC_A); if (rc1 != DEV_OK) { PRINT("Pinmux config error %d!!\n", rc1); } } /* taskA gives its own semaphore, allowing it to say hello right away */ task_sem_give(TASKASEM); /* invoke routine that allows task to ping-pong hello messages with taskB */ helloLoop(__FUNCTION__, TASKASEM, TASKBSEM); }
int pipePutWaitTest(void) { int rv; /* return code from task_pipe_put_wait() */ int bytesWritten; /* # of bytes written to pipe */ /* 1. Fill the pipe */ rv = task_pipe_put_wait(pipeId, txBuffer, PIPE_SIZE, &bytesWritten, _ALL_N); if ((rv != RC_OK) || (bytesWritten != PIPE_SIZE)) { TC_ERROR("Return code: expected %d, got %d\n" "Bytes written: expected %d, got %d\n", RC_OK, rv, PIPE_SIZE, bytesWritten); return TC_FAIL; } task_sem_give(altSem); /* Wake the alternate task */ /* 2. task_pipe_put_wait() will force a context switch to AlternateTask(). */ rv = task_pipe_put_wait(pipeId, txBuffer, PIPE_SIZE, &bytesWritten, _ALL_N); if ((rv != RC_OK) || (bytesWritten != PIPE_SIZE)) { TC_ERROR("Return code: expected %d, got %d\n" "Bytes written: expected %d, got %d\n", RC_OK, rv, PIPE_SIZE, bytesWritten); return TC_FAIL; } /* 3. task_pipe_put_wait() will force a context switch to AlternateTask(). */ rv = task_pipe_put_wait(pipeId, txBuffer, PIPE_SIZE, &bytesWritten, _1_TO_N); if ((rv != RC_OK) || (bytesWritten != PIPE_SIZE)) { TC_ERROR("Return code: expected %d, got %d\n" "Bytes written: expected %d, got %d\n", RC_OK, rv, PIPE_SIZE, bytesWritten); return TC_FAIL; } /* This should return immediately as _0_TO_N with a wait is an error. */ rv = task_pipe_put_wait(pipeId, txBuffer, PIPE_SIZE, &bytesWritten, _0_TO_N); if ((rv != RC_FAIL) || (bytesWritten != 0)) { TC_ERROR("Return code: expected %d, got %d\n" "Bytes written: expected %d, got %d\n", RC_FAIL, rv, 0, bytesWritten); return TC_FAIL; } /* Wait for AlternateTask()'s pipePutWaitHelper() to finish */ (void)task_sem_take_wait(regSem); return TC_PASS; }
int simpleGroupWaitTest(void) { int i; ksem_t sema; task_sem_give(altSem); /* Wake the alternate task */ /* * Wait for a semaphore to be signalled by the alternate task. * Each semaphore in the group will be tested. */ for (i = 0; semList[i] != ENDLIST; i++) { sema = task_sem_group_take(semList, TICKS_UNLIMITED); if (sema != semList[i]) { TC_ERROR("task_sem_group_take() error. Expected %d, not %d\n", (int) semList[i], (int) sema); return TC_FAIL; } } /* * The Alternate Task will signal the semaphore group once. Note that * when the semaphore group is signalled, the last semaphore in the * group is the value that is returned, not the first. */ for (i = 3; i >= 0; i--) { sema = task_sem_group_take(semList, TICKS_UNLIMITED); if (sema != semList[i]) { TC_ERROR("task_sem_group_take() error. Expected %d, not %d\n", (int) semList[3], (int) sema); return TC_FAIL; } } /* * Again wait for a semaphore to be signalled. This time, the alternate * task will trigger an interrupt that signals the semaphore. */ for (i = 0; semList[i] != ENDLIST; i++) { sema = task_sem_group_take(semList, TICKS_UNLIMITED); if (sema != semList[i]) { TC_ERROR("task_sem_group_take() error. Expected %d, not %d\n", (int) semList[i], (int) sema); return TC_FAIL; } } return TC_PASS; }
static void send(const char *taskname, ksem_t mySem, ksem_t otherSem, struct net_context *ctx) { int i = 0; while (1) { if (CONFIG_NET_15_4_LOOPBACK_NUM != 0 && i >= CONFIG_NET_15_4_LOOPBACK_NUM) { task_sem_give(otherSem); return; } task_sem_take(mySem, TICKS_UNLIMITED); send_data(taskname, ctx); /* wait a while, then let other task have a turn */ task_sleep(SLEEPTICKS); task_sem_give(otherSem); i++; } }
/* * * @param taskname task identification string * @param mySem task's own semaphore * @param otherSem other task's semaphore * */ void helloLoop(const char *taskname, ksem_t mySem, ksem_t otherSem) { while (1) { task_sem_take(mySem, TICKS_UNLIMITED); /* say "hello" */ PRINT("%s: Hello World!\n", taskname); /* wait a while, then let other task have a turn */ task_sleep(SLEEPTICKS); task_sem_give(otherSem); } }
int simpleSemaWaitTest(void) { int status; int i; for (i = 0; i < 5; i++) { /* Wait one second for SIMPLE_SEM. Timeout is expected. */ status = task_sem_take(simpleSem, OBJ_TIMEOUT); if (status != RC_TIME) { TC_ERROR("task_sem_take() error. Expected %d, got %d\n", RC_TIME, status); return TC_FAIL; } } /* * Signal the semaphore upon which the alternate task is waiting. The * alternate task (which is at a lower priority) will cause SIMPLE_SEM * to be signalled, thus waking this task. */ task_sem_give(altSem); status = task_sem_take(simpleSem, OBJ_TIMEOUT); if (status != RC_OK) { TC_ERROR("task_sem_take() error. Expected %d, got %d\n", RC_OK, status); return TC_FAIL; } /* * Note that task_sem_take(TICKS_UNLIMITED) has been tested when waking up * the alternate task. Since previous tests had this task waiting, the * alternate task must have had the time to enter the state where it is * waiting for the ALTTASK_SEM semaphore to be given. Thus, we do not need * to test for it here. * * Now wait on SIMPLE_SEM again. This time it will be woken up by an * ISR signalling the semaphore. */ status = task_sem_take(simpleSem, OBJ_TIMEOUT); if (status != RC_OK) { TC_ERROR("task_sem_take() error. Expected %d, got %d\n", RC_OK, status); return TC_FAIL; } return TC_PASS; }
int pipeput(kpipe_t pipe, K_PIPE_OPTION option, int size, int count, uint32_t *time) { int i; unsigned int t; int sizexferd_total = 0; int size2xfer_total = size * count; /* first sync with the receiver */ task_sem_give(SEM0); t = BENCH_START(); for (i = 0; _1_TO_N == option || (i < count); i++) { int sizexferd = 0; int size2xfer = min(size, size2xfer_total - sizexferd_total); int ret; ret = task_pipe_put_wait(pipe, data_bench, size2xfer, &sizexferd, option); if (RC_OK != ret) { return 1; } if (_ALL_N == option && sizexferd != size2xfer) { return 1; } sizexferd_total += sizexferd; if (size2xfer_total == sizexferd_total) { break; } if (size2xfer_total < sizexferd_total) { return 1; } } t = TIME_STAMP_DELTA_GET(t); *time = SYS_CLOCK_HW_CYCLES_TO_NS_AVG(t, count); if (bench_test_end() < 0) { if (high_timer_overflow()) { PRINT_STRING("| Timer overflow. Results are invalid ", output_file); } else { PRINT_STRING("| Tick occured. Results may be inaccurate ", output_file); } PRINT_STRING(" |\n", output_file); } return 0; }
void taskA(void) { struct net_context *ctx; net_init(); init_test(); ctx = get_context(&any_addr, SRC_PORT, &loopback_addr, DEST_PORT); if (!ctx) { PRINT("%s: Cannot get network context\n", __func__); return; } /* taskA gives its own semaphore, allowing it to say hello right away */ task_sem_give(TASKASEM); listen(__func__, TASKASEM, TASKBSEM, ctx); }
void pipe_test(void) { uint32_t putsize; int getsize; uint32_t puttime[3]; int putcount; int pipe; kpriority_t TaskPrio; int prio; GetInfo getinfo; task_sem_reset(SEM0); task_sem_give(STARTRCV); /* action: */ /* non-buffered operation, matching (ALL_N) */ PRINT_STRING(dashline, output_file); PRINT_STRING("| " "P I P E M E A S U R E M E N T S" " |\n", output_file); PRINT_STRING(dashline, output_file); PRINT_STRING("| Send data into a pipe towards a " "receiving high priority task and wait |\n", output_file); PRINT_STRING(dashline, output_file); PRINT_STRING("| " "matching sizes (_ALL_N)" " |\n", output_file); PRINT_STRING(dashline, output_file); PRINT_ALL_TO_N_HEADER_UNIT(); PRINT_STRING(dashline, output_file); PRINT_STRING("| put | get | no buf | small buf| big buf |" " no buf | small buf| big buf |\n", output_file); PRINT_STRING(dashline, output_file); for (putsize = 8; putsize <= MESSAGE_SIZE_PIPE; putsize <<= 1) { for (pipe = 0; pipe < 3; pipe++) { putcount = NR_OF_PIPE_RUNS; pipeput(TestPipes[pipe], _ALL_N, putsize, putcount, &puttime[pipe]); task_fifo_get_wait(CH_COMM, &getinfo); /* waiting for ack */ } PRINT_ALL_TO_N(); } PRINT_STRING(dashline, output_file); /* Test with two different sender priorities */ for (prio = 0; prio < 2; prio++) { /* non-buffered operation, non-matching (1_TO_N) */ if (prio == 0) { PRINT_STRING("| " "non-matching sizes (1_TO_N) to higher priority" " |\n", output_file); TaskPrio = task_priority_get(); } if (prio == 1) { PRINT_STRING("| " "non-matching sizes (1_TO_N) to lower priority" " |\n", output_file); task_priority_set(task_id_get(), TaskPrio - 2); } PRINT_STRING(dashline, output_file); PRINT_1_TO_N_HEADER(); PRINT_STRING("| put | get | no buf | small buf| big buf | " "no buf | small buf| big buf |\n", output_file); PRINT_STRING(dashline, output_file); for (putsize = 8; putsize <= (MESSAGE_SIZE_PIPE); putsize <<= 1) { putcount = MESSAGE_SIZE_PIPE / putsize; for (pipe = 0; pipe < 3; pipe++) { pipeput(TestPipes[pipe], _1_TO_N, putsize, putcount, &puttime[pipe]); /* size*count == MESSAGE_SIZE_PIPE */ task_fifo_get_wait(CH_COMM, &getinfo); /* waiting for ack */ getsize = getinfo.size; } PRINT_1_TO_N(); } PRINT_STRING(dashline, output_file); task_priority_set(task_id_get(), TaskPrio); } }
int pipePutHelperWork(SIZE_EXPECT *singleItems, int nSingles, SIZE_EXPECT *manyItems, int nMany) { int i; /* loop counter */ int j; /* loop counter */ int rv; /* value returned from task_pipe_get() */ int index; /* index to corrupted byte in buffer */ int bytesReceived; /* number of bytes received */ for (i = 0; i < nSingles; i++) { (void)task_sem_take_wait(altSem); for (j = 0; j < sizeof(rxBuffer); j++) { rxBuffer[j] = 0; } rv = task_pipe_get(pipeId, rxBuffer, singleItems[i].size, &bytesReceived, singleItems[i].options); if (rv != singleItems[i].rcode) { TC_ERROR("task_pipe_get(%d bytes) : Expected %d not %d.\n" " bytesReceived = %d\n", singleItems[i].size, singleItems[i].rcode, rv, bytesReceived); return TC_FAIL; } if (bytesReceived != singleItems[i].sent) { TC_ERROR("task_pipe_get(%d) : " "Expected %d bytes to be received, not %d\n", singleItems[i].size, singleItems[i].sent, bytesReceived); return TC_FAIL; } index = receiveBufferCheck(rxBuffer, bytesReceived); if (index != bytesReceived) { TC_ERROR("pipePutHelper: rxBuffer[%d] is %d, not %d\n", index, rxBuffer[index], index); return TC_FAIL; } task_sem_give(counterSem); task_sem_give(regSem); } /* * Get items from the pipe. There should be more than one item * stored in it. */ (void)task_sem_take_wait(altSem); for (i = 0; i < nMany; i++) { for (j = 0; j < sizeof(rxBuffer); j++) { rxBuffer[j] = 0; } rv = task_pipe_get(pipeId, rxBuffer, manyItems[i].size, &bytesReceived, manyItems[i].options); if (rv != manyItems[i].rcode) { TC_ERROR("task_pipe_get(%d bytes) : Expected %d not %d.\n" " bytesReceived = %d, iteration: %d\n", manyItems[i].size, manyItems[i].rcode, rv, bytesReceived, i+1); return TC_FAIL; } if (bytesReceived != manyItems[i].sent) { TC_ERROR("task_pipe_get(%d) : " "Expected %d bytes to be received, not %d\n", manyItems[i].size, manyItems[i].sent, bytesReceived); return TC_FAIL; } index = receiveBufferCheck(rxBuffer, bytesReceived); if (index != bytesReceived) { TC_ERROR("pipeGetHelper: rxBuffer[%d] is %d, not %d\n", index, rxBuffer[index], index); return TC_FAIL; } task_sem_give(counterSem); } task_sem_give(regSem); /* Wake the RegressionTask */ return TC_PASS; }
int pipePutTestWork(SIZE_EXPECT *singleItems, int nSingles, SIZE_EXPECT *manyItems, int nMany) { int rv; /* return code from task_pipe_put() */ int i; /* loop counter */ int bytesWritten; /* # of bytes sent to pipe */ int nitem; /* expected item number processed by the other task */ task_sem_reset(counterSem); for (i = 0; i < nSingles; i++) { rv = task_pipe_put(pipeId, txBuffer, singleItems[i].size, &bytesWritten, singleItems[i].options); if (rv != singleItems[i].rcode) { TC_ERROR("task_pipe_put(%d) : Expected %d not %d.\n" " bytesWritten = %d, Iteration: %d\n", singleItems[i].size, singleItems[i].rcode, rv, bytesWritten, i + 1); return TC_FAIL; } if (bytesWritten != singleItems[i].sent) { TC_ERROR("task_pipe_put(%d) : " "Expected %d bytes to be written, not %d\n", singleItems[i].size, singleItems[i].sent, bytesWritten); return TC_FAIL; } task_sem_give(altSem); (void)task_sem_take_wait(regSem); nitem = task_sem_count_get(counterSem) - 1; if (nitem != i) { TC_ERROR("Expected item number is %d, not %d\n", i, nitem); return TC_FAIL; } } /* This time, more than one item will be in the pipe at a time */ task_sem_reset(counterSem); for (i = 0; i < nMany; i++) { rv = task_pipe_put(pipeId, txBuffer, manyItems[i].size, &bytesWritten, manyItems[i].options); if (rv != manyItems[i].rcode) { TC_ERROR("task_pipe_put(%d) : Expected %d not %d.\n" " bytesWritten = %d, iteration: %d\n", manyItems[i].size, manyItems[i].rcode, rv, bytesWritten, i + 1); return TC_FAIL; } if (bytesWritten != manyItems[i].sent) { TC_ERROR("task_pipe_put(%d) : " "Expected %d bytes to be written, not %d\n", manyItems[i].size, manyItems[i].sent, bytesWritten); return TC_FAIL; } } task_sem_give(altSem); /* Wake the alternate task */ /* wait for other task reading all the items from pipe */ (void)task_sem_take_wait(regSem); if (task_sem_count_get(counterSem) != nMany) { TC_ERROR("Expected number of items %d, not %d\n", nMany, task_sem_count_get(counterSem)); return TC_FAIL; } return TC_PASS; }
/** * * @brief Semaphore signal speed test * * @return N/A */ void sema_test(void) { uint32_t et; /* elapsed Time */ int i; PRINT_STRING(dashline, output_file); et = BENCH_START(); for (i = 0; i < NR_OF_SEMA_RUNS; i++) { task_sem_give(SEM0); } et = TIME_STAMP_DELTA_GET(et); check_result(); PRINT_F(output_file, FORMAT, "signal semaphore", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_SEMA_RUNS)); task_sem_reset(SEM1); task_sem_give(STARTRCV); et = BENCH_START(); for (i = 0; i < NR_OF_SEMA_RUNS; i++) { task_sem_give(SEM1); } et = TIME_STAMP_DELTA_GET(et); check_result(); PRINT_F(output_file, FORMAT, "signal to waiting high pri task", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_SEMA_RUNS)); et = BENCH_START(); for (i = 0; i < NR_OF_SEMA_RUNS; i++) { task_sem_give(SEM1); } et = TIME_STAMP_DELTA_GET(et); check_result(); PRINT_F(output_file, FORMAT, "signal to waiting high pri task, with timeout", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_SEMA_RUNS)); et = BENCH_START(); for (i = 0; i < NR_OF_SEMA_RUNS; i++) { task_sem_give(SEM2); } et = TIME_STAMP_DELTA_GET(et); check_result(); PRINT_F(output_file, FORMAT, "signal to waitm (2)", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_SEMA_RUNS)); et = BENCH_START(); for (i = 0; i < NR_OF_SEMA_RUNS; i++) { task_sem_give(SEM2); } et = TIME_STAMP_DELTA_GET(et); check_result(); PRINT_F(output_file, FORMAT, "signal to waitm (2), with timeout", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_SEMA_RUNS)); et = BENCH_START(); for (i = 0; i < NR_OF_SEMA_RUNS; i++) { task_sem_give(SEM3); } et = TIME_STAMP_DELTA_GET(et); check_result(); PRINT_F(output_file, FORMAT, "signal to waitm (3)", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_SEMA_RUNS)); et = BENCH_START(); for (i = 0; i < NR_OF_SEMA_RUNS; i++) { task_sem_give(SEM3); } et = TIME_STAMP_DELTA_GET(et); check_result(); PRINT_F(output_file, FORMAT, "signal to waitm (3), with timeout", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_SEMA_RUNS)); et = BENCH_START(); for (i = 0; i < NR_OF_SEMA_RUNS; i++) { task_sem_give(SEM4); } et = TIME_STAMP_DELTA_GET(et); check_result(); PRINT_F(output_file, FORMAT, "signal to waitm (4)", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_SEMA_RUNS)); et = BENCH_START(); for (i = 0; i < NR_OF_SEMA_RUNS; i++) { task_sem_give(SEM4); } et = TIME_STAMP_DELTA_GET(et); check_result(); PRINT_F(output_file, FORMAT, "signal to waitm (4), with timeout", SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_SEMA_RUNS)); }
int simpleSemaTest(void) { int signalCount; int i; int status; /* * Signal the semaphore several times from an ISR. After each signal, * check the signal count. */ for (i = 0; i < 5; i++) { trigger_isrSemaSignal(simpleSem); task_sleep(10); /* Time for low priority task to run. */ signalCount = task_sem_count_get(simpleSem); if (signalCount != (i + 1)) { TC_ERROR("<signalCount> error. Expected %d, got %d\n", i + 1, signalCount); return TC_FAIL; } } /* * Signal the semaphore several times from a task. After each signal, * check the signal count. */ for (i = 5; i < 10; i++) { task_sem_give(simpleSem); signalCount = task_sem_count_get(simpleSem); if (signalCount != (i + 1)) { TC_ERROR("<signalCount> error. Expected %d, got %d\n", i + 1, signalCount); return TC_FAIL; } } /* * Test the semaphore without wait. Check the signal count after each * attempt (it should be decrementing by 1 each time). */ for (i = 9; i >= 4; i--) { status = task_sem_take(simpleSem, TICKS_NONE); if (status != RC_OK) { TC_ERROR("task_sem_take(SIMPLE_SEM) error. Expected %d, not %d.\n", RC_OK, status); return TC_FAIL; } signalCount = task_sem_count_get(simpleSem); if (signalCount != i) { TC_ERROR("<signalCount> error. Expected %d, not %d\n", i, signalCount); return TC_FAIL; } } task_sem_reset(simpleSem); /* * The semaphore's signal count should now be zero (0). Test the * semaphore without wait. It should fail. */ for (i = 0; i < 10; i++) { status = task_sem_take(simpleSem, TICKS_NONE); if (status != RC_FAIL) { TC_ERROR("task_sem_take(SIMPLE_SEM) error. Expected %d, got %d.\n", RC_FAIL, status); return TC_FAIL; } signalCount = task_sem_count_get(simpleSem); if (signalCount != 0) { TC_ERROR("<signalCount> error. Expected %d, not %d\n", 0, signalCount); return TC_FAIL; } } return TC_PASS; }
int RegressionTask(void) { int tcRC; int value; ksem_t semBlockList[4]; semBlockList[0] = blockHpSem; semBlockList[1] = blockMpSem; semBlockList[2] = blockLpSem; semBlockList[3] = ENDLIST; /* Signal a semaphore that has no waiting tasks. */ TC_PRINT("Signal and test a semaphore without blocking\n"); tcRC = simpleSemaTest(); if (tcRC != TC_PASS) { return TC_FAIL; } /* Wait on a semaphore. */ TC_PRINT("Signal and test a semaphore with blocking\n"); tcRC = simpleSemaWaitTest(); if (tcRC != TC_PASS) { return TC_FAIL; } /* * Have many tasks wait on a semaphore (MANY_BLOCKED_SEM). They will * block in the following order: * LowPriorityTask (low priority) * HighPriorityTask (high priority) * AlternateTask (medium priority) * * When the semaphore (MANY_BLOCKED_SEM) is signalled, HighPriorityTask * will be woken first. * */ TC_PRINT("Testing many tasks blocked on the same semaphore\n"); task_sleep(OBJ_TIMEOUT); /* Time for low priority task to run. */ task_sem_give(hpSem); /* Wake high priority task */ task_sem_give(altSem); /* Wake alternate task (medium priority) */ task_sleep(OBJ_TIMEOUT); /* Give alternate task time to run */ task_sem_give(manyBlockSem); task_sleep(OBJ_TIMEOUT); /* Ensure high priority task can run */ value = task_sem_group_take(semBlockList, OBJ_TIMEOUT); if (value != blockHpSem) { TC_ERROR("%s priority task did not get semaphore: 0x%x\n", "High", value); return TC_FAIL; } task_sem_give(manyBlockSem); task_sleep(OBJ_TIMEOUT); /* Ensure medium priority task can run */ value = task_sem_group_take(semBlockList, OBJ_TIMEOUT); if (value != blockMpSem) { TC_ERROR("%s priority task did not get semaphore: 0x%x\n", "Medium", value); return TC_FAIL; } task_sem_give(manyBlockSem); task_sleep(OBJ_TIMEOUT); /* Ensure low priority task can run */ value = task_sem_group_take(semBlockList, OBJ_TIMEOUT); if (value != blockLpSem) { TC_ERROR("%s priority task did not get semaphore: 0x%x\n", "Low", value); return TC_FAIL; } value = task_sem_group_take(semBlockList, OBJ_TIMEOUT); if (value != ENDLIST) { TC_ERROR("Group test Expecting ENDLIST, but got 0x%x\n", value); return TC_FAIL; } TC_PRINT("Testing semaphore groups without blocking\n"); tcRC = simpleGroupTest(); if (tcRC != TC_PASS) { return TC_FAIL; } TC_PRINT("Testing semaphore groups with blocking\n"); tcRC = simpleGroupWaitTest(); if (tcRC != TC_PASS) { return TC_FAIL; } TC_PRINT("Testing semaphore release by fiber\n"); tcRC = simpleFiberSemTest(); if (tcRC != TC_PASS) { return TC_FAIL; } return TC_PASS; }
int AlternateTask(void) { int status; int i; /* Wait until it is time to continue */ status = task_sem_take(altSem, TICKS_UNLIMITED); if (status != RC_OK) { TC_ERROR("task_sem_take() error. Expected %d, got %d\n", RC_OK, status); return TC_FAIL; } /* * After signalling the semaphore upon which the main (RegressionTask) task * is waiting, control will pass back to the main (RegressionTask) task. */ task_sem_give(simpleSem); /* * Control has returned to the alternate task. Trigger an ISR that will * signal the semaphore upon which RegressionTask is waiting. */ trigger_isrSemaSignal(simpleSem); /* Wait for RegressionTask to wake this task up */ status = task_sem_take(altSem, TICKS_UNLIMITED); if (status != RC_OK) { TC_ERROR("task_sem_take() error. Expected %d, got %d", RC_OK, status); return TC_FAIL; } /* Wait on a semaphore that will have many waiters */ status = task_sem_take(manyBlockSem, TICKS_UNLIMITED); if (status != RC_OK) { TC_ERROR("task_sem_take() error. Expected %d, got %d", RC_OK, status); return TC_FAIL; } /* Inform Regression test MP task is no longer blocked on MANY_BLOCKED_SEM*/ task_sem_give(blockMpSem); /* Wait until the alternate task is needed again */ status = task_sem_take(altSem, TICKS_UNLIMITED); if (status != RC_OK) { TC_ERROR("task_sem_take() error. Expected %d, got %d", RC_OK, status); return TC_FAIL; } for (i = 0; semList[i] != ENDLIST; i++) { task_sem_give(semList[i]); /* Context switch back to Regression Task */ } task_sem_group_give(semList); /* Context switch back to Regression Task */ for (i = 0; semList[i] != ENDLIST; i++) { trigger_isrSemaSignal(semList[i]); /* Context switch back to Regression Task */ } return TC_PASS; }
void RegressionTask(void) { int retValue; /* task_mem_map_xxx interface return value */ void *b; /* Pointer to memory block */ void *ptr[NUMBLOCKS]; /* Pointer to memory block */ /* Part 1 of test */ TC_START("Test Microkernel Memory Maps"); TC_PRINT("Starts %s\n", __func__); /* Test task_mem_map_alloc */ tcRC = testMapGetAllBlocks(ptr); if (tcRC == TC_FAIL) { TC_ERROR("Failed testMapGetAllBlocks function\n"); goto exitTest; /* terminate test */ } printPointers(ptr); /* Test task_mem_map_free */ tcRC = testMapFreeAllBlocks(ptr); if (tcRC == TC_FAIL) { TC_ERROR("Failed testMapFreeAllBlocks function\n"); goto exitTest; /* terminate test */ } printPointers(ptr); task_sem_give(SEM_REGRESSDONE); /* Allow HelperTask to run */ /* Wait for HelperTask to finish */ task_sem_take(SEM_HELPERDONE, TICKS_UNLIMITED); /* * Part 3 of test. * * HelperTask got all memory blocks. There is no free block left. * The call will timeout. Note that control does not switch back to * HelperTask as it is waiting for SEM_REGRESSDONE. */ retValue = task_mem_map_alloc(MAP_LgBlks, &b, 2); if (verifyRetValue(RC_TIME, retValue)) { TC_PRINT("%s: task_mem_map_alloc timeout expected\n", __func__); } else { TC_ERROR("Failed task_mem_map_alloc, retValue %d\n", retValue); tcRC = TC_FAIL; goto exitTest; /* terminate test */ } TC_PRINT("%s: start to wait for block\n", __func__); task_sem_give(SEM_REGRESSDONE); /* Allow HelperTask to run part 4 */ retValue = task_mem_map_alloc(MAP_LgBlks, &b, 5); if (verifyRetValue(RC_OK, retValue)) { TC_PRINT("%s: task_mem_map_alloc OK, block allocated at %p\n", __func__, b); } else { TC_ERROR("Failed task_mem_map_alloc, retValue %d\n", retValue); tcRC = TC_FAIL; goto exitTest; /* terminate test */ } /* Wait for HelperTask to complete */ task_sem_take(SEM_HELPERDONE, TICKS_UNLIMITED); TC_PRINT("%s: start to wait for block\n", __func__); task_sem_give(SEM_REGRESSDONE); /* Allow HelperTask to run part 5 */ retValue = task_mem_map_alloc(MAP_LgBlks, &b, TICKS_UNLIMITED); if (verifyRetValue(RC_OK, retValue)) { TC_PRINT("%s: task_mem_map_alloc OK, block allocated at %p\n", __func__, b); } else { TC_ERROR("Failed task_mem_map_alloc, retValue %d\n", retValue); tcRC = TC_FAIL; goto exitTest; /* terminate test */ } /* Wait for HelperTask to complete */ task_sem_take(SEM_HELPERDONE, TICKS_UNLIMITED); /* Free memory block */ TC_PRINT("%s: Used %d block\n", __func__, task_mem_map_used_get(MAP_LgBlks)); task_mem_map_free(MAP_LgBlks, &b); TC_PRINT("%s: 1 block freed, used %d block\n", __func__, task_mem_map_used_get(MAP_LgBlks)); exitTest: TC_END_RESULT(tcRC); TC_END_REPORT(tcRC); } /* RegressionTask */