/* * ======== Core_unlock ======== */ Void Core_unlock() { // TODO Check BIOS.swiEnabled and BIOS.taskEnabled before using // Task_enabled() and Swi_enabled() APIs as Tasking/Swis // may be disabled. if (Task_enabled() && Swi_enabled()) { GateSmp_leave(Core_gate, 0); } }
/* * ======== Core_unlock ======== */ Void Core_unlock() { UInt hwiKey, coreId; /* Hwi_disable() */ hwiKey = _set_interrupt_priority(Hwi_disablePriority); coreId = Core_getId(); // TODO Check BIOS.swiEnabled and BIOS.taskEnabled before using // Task_enabled() and Swi_enabled() APIs. if (Core_module->gateEntered[coreId]) { if (Task_enabled() && Swi_enabled()) { GateSmp_leave(Core_gate, 0); Core_module->gateEntered[coreId] = FALSE; } } /* Hwi_restore() */ _set_interrupt_priority(hwiKey); }
/* * ======== Event_pend ======== */ UInt Event_pend(Event_Object *event, UInt andMask, UInt orMask, UInt32 timeout) { UInt hwiKey, tskKey; Event_PendElem elem; UInt matchingEvents; Queue_Handle pendQ; Clock_Struct clockStruct; Assert_isTrue(((andMask | orMask) != 0), Event_A_nullEventMasks); Log_write5(Event_LM_pend, (UArg)event, (UArg)event->postedEvents, (UArg)andMask, (UArg)orMask, (IArg)((Int)timeout)); /* * elem is filled in entirely before interrupts are disabled. * This significantly reduces latency at the potential cost of wasted time * if it turns out that there is already an event match. */ /* add Clock event if timeout is not FOREVER nor NO_WAIT */ if (BIOS_clockEnabled && (timeout != BIOS_WAIT_FOREVER) && (timeout != BIOS_NO_WAIT)) { Clock_addI(Clock_handle(&clockStruct), (Clock_FuncPtr)Event_pendTimeout, timeout, (UArg)&elem); elem.tpElem.clock = Clock_handle(&clockStruct); elem.pendState = Event_PendState_CLOCK_WAIT; } else { elem.tpElem.clock = NULL; elem.pendState = Event_PendState_WAIT_FOREVER; } /* fill in this task's Event_PendElem */ elem.andMask = andMask; elem.orMask = orMask; pendQ = Event_Instance_State_pendQ(event); /* get task handle */ elem.tpElem.task = Task_self(); /* Atomically check for a match and block if none */ hwiKey = Hwi_disable(); /* check if events are already available */ matchingEvents = Event_checkEvents(event, andMask, orMask); if (matchingEvents != 0) { /* remove Clock object from Clock Q */ if (BIOS_clockEnabled && (elem.tpElem.clock != NULL)) { Clock_removeI(elem.tpElem.clock); elem.tpElem.clock = NULL; } Hwi_restore(hwiKey); return (matchingEvents);/* yes, then return with matching bits */ } if (timeout == BIOS_NO_WAIT) { Hwi_restore(hwiKey); return (0); /* No match, no wait */ } Assert_isTrue((BIOS_getThreadType() == BIOS_ThreadType_Task), Event_A_badContext); /* * Verify that THIS core hasn't already disabled the scheduler * so that the Task_restore() call below will indeed block */ Assert_isTrue((Task_enabled()), Event_A_pendTaskDisabled); /* lock scheduler */ tskKey = Task_disable(); /* only one Task allowed!!! */ Assert_isTrue(Queue_empty(pendQ), Event_A_eventInUse); /* leave a pointer for Task_delete() */ elem.tpElem.task->pendElem = (Task_PendElem *)&(elem); /* add it to Event_PendElem queue */ Queue_enqueue(pendQ, (Queue_Elem *)&elem); Task_blockI(elem.tpElem.task); if (BIOS_clockEnabled && (elem.pendState == Event_PendState_CLOCK_WAIT)) { Clock_startI(elem.tpElem.clock); } Hwi_restore(hwiKey); /* unlock task scheduler and block */ Task_restore(tskKey); /* the calling task will switch out here */ /* Here on unblock due to Event_post or Event_pendTimeout */ hwiKey = Hwi_disable(); /* remove Clock object from Clock Q */ if (BIOS_clockEnabled && (elem.tpElem.clock != NULL)) { Clock_removeI(elem.tpElem.clock); elem.tpElem.clock = NULL; } elem.tpElem.task->pendElem = NULL; Hwi_restore(hwiKey); /* event match? */ if (elem.pendState != Event_PendState_TIMEOUT) { return (elem.matchingEvents); } else { return (0); /* timeout */ } }
/* * ======== 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; }