/* * ======== Task_exit ======== */ Void Task_exit() { UInt tskKey, hwiKey; Task_Object *tsk; #ifndef ti_sysbios_knl_Task_DISABLE_ALL_HOOKS Int i; #endif tsk = Task_self(); #ifndef ti_sysbios_knl_Task_DISABLE_ALL_HOOKS /* * Process Task_exit hooks. Should be called outside the Task kernel. */ for (i = 0; i < Task_hooks.length; i++) { if (Task_hooks.elem[i].exitFxn != NULL) { Task_hooks.elem[i].exitFxn(tsk); } } #endif Log_write2(Task_LD_exit, (UArg)tsk, (UArg)tsk->fxn); tskKey = Task_disable(); hwiKey = Hwi_disable(); Task_blockI(tsk); tsk->mode = Task_Mode_TERMINATED; Task_processVitalTaskFlag(tsk); Hwi_restore(hwiKey); Queue_elemClear((Queue_Elem *)tsk); /* add to terminated task list if it was dynamically created */ if (Task_deleteTerminatedTasks == TRUE) { Task_Handle dynTask; dynTask = Task_Object_first(); while (dynTask) { if (tsk == dynTask) { tsk->readyQ = Task_Module_State_terminatedQ(); Queue_put(tsk->readyQ, (Queue_Elem *)tsk); break; } else { dynTask = Task_Object_next(dynTask); } } } Task_restore(tskKey); }
/* * ======== Task_sleep ======== */ Void Task_sleep(UInt timeout) { Task_PendElem elem; UInt hwiKey, tskKey; Clock_Struct clockStruct; if (timeout == BIOS_NO_WAIT) { return; } Assert_isTrue((timeout != BIOS_WAIT_FOREVER), Task_A_badTimeout); /* add Clock event if timeout is not FOREVER */ if (BIOS_clockEnabled) { Clock_Params clockParams; Clock_Params_init(&clockParams); clockParams.arg = (UArg)&elem; clockParams.startFlag = FALSE; /* will start when necessary, thankyou */ Clock_construct(&clockStruct, (Clock_FuncPtr)Task_sleepTimeout, timeout, &clockParams); elem.clock = Clock_handle(&clockStruct); } hwiKey = Hwi_disable(); /* lock scheduler */ tskKey = Task_disable(); /* get task handle and block tsk */ elem.task = Task_self(); Task_blockI(elem.task); if (BIOS_clockEnabled) { Clock_startI(elem.clock); } /* Only needed for Task_delete() */ Queue_elemClear(&elem.qElem); elem.task->pendElem = (Ptr)(&elem); Hwi_restore(hwiKey); Log_write3(Task_LM_sleep, (UArg)elem.task, (UArg)elem.task->fxn, (UArg)timeout); Task_restore(tskKey); /* the calling task will block here */ /* deconstruct Clock if appropriate */ if (BIOS_clockEnabled) { Clock_destruct(Clock_struct(elem.clock)); } }
/* * ======== Swi_Instance_init ======== */ Int Swi_Instance_init(Swi_Object *swi, Swi_FuncPtr fxn, const Swi_Params *params, Error_Block *eb) { Int status; Assert_isTrue((BIOS_swiEnabled == TRUE), Swi_A_swiDisabled); Queue_elemClear(&swi->qElem); swi->fxn = fxn; swi->arg0 = params->arg0; swi->arg1 = params->arg1; if (params->priority == ~0) { swi->priority = Swi_numPriorities - 1; } else { swi->priority = params->priority; } Assert_isTrue((swi->priority < Swi_numPriorities), Swi_A_badPriority); swi->mask = 1 << swi->priority; swi->posted = FALSE; swi->initTrigger = swi->trigger = params->trigger; swi->readyQ = Queue_Object_get(Swi_module->readyQ, swi->priority); #ifndef ti_sysbios_knl_Swi_DISABLE_ALL_HOOKS if (Swi_hooks.length > 0) { swi->hookEnv = Memory_alloc(Swi_Object_heap(), Swi_hooks.length * sizeof(Ptr), 0, eb); if (swi->hookEnv == NULL) { return (1); /* see 2 below */ } } #endif status = Swi_postInit(swi, eb); /* * floor of 2 here is to differentiate Swi_postInit errors * from Instance_init errors */ if (Error_check(eb)) { return (2 + status); } return (0); }
/* * ======== Task_sleep ======== */ Void Task_sleep(UInt32 timeout) { Task_PendElem elem; UInt hwiKey, tskKey; Clock_Struct clockStruct; if (timeout == BIOS_NO_WAIT) { return; } Assert_isTrue((timeout != BIOS_WAIT_FOREVER), Task_A_badTimeout); /* * BIOS_clockEnabled check is here to eliminate Clock module * references in the custom library */ if (BIOS_clockEnabled) { /* add Clock event */ Clock_addI(Clock_handle(&clockStruct), (Clock_FuncPtr)Task_sleepTimeout, timeout, (UArg)&elem); elem.clock = Clock_handle(&clockStruct); } hwiKey = Hwi_disable(); /* * Verify that THIS core hasn't already disabled the scheduler * so that the Task_restore() call below will indeed block */ Assert_isTrue((Task_enabled()), Task_A_sleepTaskDisabled); /* lock scheduler */ tskKey = Task_disable(); /* get task handle and block tsk */ elem.task = Task_self(); Task_blockI(elem.task); /* * BIOS_clockEnabled check is here to eliminate Clock module * references in the custom library */ if (BIOS_clockEnabled) { Clock_startI(elem.clock); } /* Only needed for Task_delete() */ Queue_elemClear(&elem.qElem); elem.task->pendElem = (Ptr)(&elem); Hwi_restore(hwiKey); Log_write3(Task_LM_sleep, (UArg)elem.task, (UArg)elem.task->fxn, (UArg)timeout); /* unlock task scheduler and block */ Task_restore(tskKey); /* the calling task will block here */ /* * BIOS_clockEnabled check is here to eliminate Clock module * references in the custom library */ if (BIOS_clockEnabled) { hwiKey = Hwi_disable(); /* remove Clock object from Clock Q */ Clock_removeI(elem.clock); elem.clock = NULL; Hwi_restore(hwiKey); } elem.task->pendElem = NULL; }
/* * ======== pthread_create ======== */ int pthread_create(pthread_t *newthread, const pthread_attr_t *attr, void *(*startroutine)(void *), void *arg) { Semaphore_Params semParams; Task_Params taskParams; pthread_Obj *thread = NULL; Error_Block eb; pthread_attr_t *pAttr; Error_init(&eb); Task_Params_init(&taskParams); *newthread = NULL; thread = (pthread_Obj *)Memory_alloc(Task_Object_heap(), sizeof(pthread_Obj), 0, &eb); if (thread == NULL) { return (ENOMEM); } pAttr = (attr == NULL) ? &defaultPthreadAttrs : (pthread_attr_t *)attr; taskParams.priority = pAttr->priority; taskParams.stack = pAttr->stack; taskParams.stackSize = pAttr->stacksize + pAttr->guardsize; /* Save the function in arg0 for ROV */ taskParams.arg0 = (UArg)startroutine; taskParams.arg1 = (UArg)thread; taskParams.env = arg; taskParams.priority = -1; thread->detached = (pAttr->detachstate == PTHREAD_CREATE_JOINABLE) ? 0 : 1; thread->fxn = startroutine; thread->joinThread = NULL; thread->cancelState = PTHREAD_CANCEL_ENABLE; thread->cancelPending = 0; thread->priority = pAttr->priority; thread->cleanupList = NULL; #if ti_sysbios_posix_Settings_supportsMutexPriority__D thread->blockedMutex = NULL; Queue_elemClear((Queue_Elem *)thread); Queue_construct(&(thread->mutexList), NULL); #endif Semaphore_Params_init(&semParams); semParams.mode = Semaphore_Mode_BINARY; Semaphore_construct(&(thread->joinSem), 0, &semParams); thread->task = Task_create((Task_FuncPtr)_pthread_runStub, &taskParams, &eb); if (thread->task == NULL) { Semaphore_destruct(&(thread->joinSem)); #if ti_sysbios_posix_Settings_supportsMutexPriority__D Queue_destruct(&(thread->mutexList)); #endif Memory_free(Task_Object_heap(), thread, sizeof(pthread_Obj)); return (ENOMEM); } *newthread = (pthread_t)thread; Task_setPri(thread->task, pAttr->priority); return (0); }