/* * ======== Power_unregisterConstraint ======== * Unregister for a power notification. * */ Power_Status Power_unregisterConstraint(Power_ConstraintHandle handle) { Power_Status status = Power_SOK; Power_Constraint type; UInt key; /* check for NULL constraintHandle */ if (handle == NULL) { status = Power_EINVALIDHANDLE; } /* else, remove and delete constraint object, update aggregate constraint */ else { key = Hwi_disable(); Queue_remove((Queue_Elem *)handle); Hwi_restore(key); /* recompute aggregate constraint w/absence of removed constraint */ type = ((Power_ConstraintObj *) handle)->type; Power_rebuildConstraint(type); /* free the constraint object */ Memory_free(Power_Object_heap(), handle, sizeof(Power_ConstraintObj)); } return (status); }
/* * ======== Event_pendTimeout ======== * called by Clock when timeout for a event expires */ Void Event_pendTimeout(UArg arg) { UInt hwiKey; Event_PendElem *elem = (Event_PendElem *)xdc_uargToPtr(arg); hwiKey = Hwi_disable(); /* * Verify that Event_post() hasn't already serviced this qElem. */ if (elem->pendState == Event_PendState_CLOCK_WAIT) { /* remove eventElem from event_Elem queue */ Queue_remove((Queue_Elem *)elem); elem->pendState = Event_PendState_TIMEOUT; /* * put task back into readyQ * No need for Task_disable/restore sandwich since this * is called within Swi (or Hwi) thread */ Task_unblockI(elem->tpElem.task, hwiKey); } Hwi_restore(hwiKey); }
/* * ======== Semaphore_pendTimeout ======== * called by Clock when timeout for a semaphore expires */ Void Semaphore_pendTimeout(UArg arg) { UInt hwiKey; Semaphore_PendElem *elem = (Semaphore_PendElem *)arg; hwiKey = Hwi_disable(); /* Verify that Semaphore_post() hasn't already occurred */ if (elem->pendState == Semaphore_PendState_CLOCK_WAIT) { /* remove task's qElem from semaphore queue */ Queue_remove((Queue_Elem *)elem); elem->pendState = Semaphore_PendState_TIMEOUT; /* * put task back into readyQ * No need for Task_disable/restore sandwich since this * is called within Swi thread */ Task_unblockI(elem->tpElem.task, hwiKey); } Hwi_restore(hwiKey); }
/* * ======== Power_unregisterNotify ======== * Unregister for a power notification. * */ Void Power_unregisterNotify(Power_NotifyObj * pNotifyObj) { UInt key; /* remove notify object from its event queue */ key = Hwi_disable(); Queue_remove((Queue_Elem *)pNotifyObj); Hwi_restore(key); }
/* * ======== Event_post ======== */ Void Event_post(Event_Object *event, UInt eventId) { UInt tskKey, hwiKey; Event_PendElem *elem; Queue_Handle pendQ; Assert_isTrue((eventId != 0), Event_A_nullEventId); Log_write3(Event_LM_post, (UArg)event, (UArg)event->postedEvents, (UArg)eventId); pendQ = Event_Instance_State_pendQ(event); /* atomically post this event */ hwiKey = Hwi_disable(); /* or in this eventId */ event->postedEvents |= eventId; /* confirm that ANY tasks are pending on this event */ if (Queue_empty(pendQ)) { Hwi_restore(hwiKey); return; } tskKey = Task_disable(); /* examine pendElem on pendQ */ elem = (Event_PendElem *)Queue_head(pendQ); /* check for match, consume matching eventIds if so. */ elem->matchingEvents = Event_checkEvents(event, elem->andMask, elem->orMask); if (elem->matchingEvents != 0) { /* remove event elem from elem queue */ Queue_remove((Queue_Elem *)elem); /* mark the Event as having been posted */ elem->pendState = Event_PendState_POSTED; /* disable Clock object */ if (BIOS_clockEnabled && (elem->tpElem.clock != NULL)) { Clock_stop(elem->tpElem.clock); } /* put task back into readyQ */ Task_unblockI(elem->tpElem.task, hwiKey); } Hwi_restore(hwiKey); /* context switch may occur here */ Task_restore(tskKey); }
void *Queue_dequeue(Queue *queue) { pthread_mutex_lock(&(queue->mutex)); ListNode *node = queue->first; if (node != NULL) { return Queue_remove(queue, node); } else { pthread_mutex_unlock(&(queue->mutex)); return NULL; } }
/* * ======== Clock_Instance_finalize ======== */ Void Clock_Instance_finalize(Clock_Object *obj) { UInt key; Assert_isTrue(((BIOS_getThreadType() != BIOS_ThreadType_Hwi) && (BIOS_getThreadType() != BIOS_ThreadType_Swi)), Clock_A_badThreadType); key = Hwi_disable(); Queue_remove(&obj->elem); Hwi_restore(key); }
void Mutex_unlock(MutexPtr mutex, PcbPtr pcb) { // Do nothing if the mutex or pcb are null, and if another pcb tries to unlock someone elses mutex. if (mutex == 0 || pcb == 0 || mutex->owner != pcb->PID) return; // Just switch the pcb from the queue (if any) to the owner position. mutex->owner = 0; if (Queue_size(&mutex->waitingQueue) > 0) { mutex->owner = Queue_remove(&mutex->waitingQueue)->PID; } }
/* * ======== Task_blockI ======== * Block a task. * * Remove a task from its ready list. * Must be called within Task_disable/Task_restore block * and with interrupts disabled */ Void Task_blockI(Task_Object *tsk) { Queue_Object *readyQ = tsk->readyQ; UInt curset = Task_module->curSet; UInt mask = tsk->mask; Log_write2(Task_LD_block, (UArg)tsk, (UArg)tsk->fxn); Queue_remove((Queue_Elem *)tsk); /* if last task in readyQ, remove corresponding bit in curSet */ if (Queue_empty(readyQ)) { Task_module->curSet = curset & ~mask; } if (Task_module->curTask == tsk) { Task_module->curQ = NULL; /* force a Task_switch() */ } tsk->mode = Task_Mode_BLOCKED; Task_module->workFlag = 1; }
/* * ======== Swi_setAttrs ======== */ Void Swi_setAttrs(Swi_Object *swi, Swi_FuncPtr fxn, Swi_Params *params) { UInt hwiKey; Swi_Params swiParams; if (params == NULL) { Swi_Params_init(&swiParams); params = &swiParams; } hwiKey = Hwi_disable(); /* defensively remove swi from its readyQ */ Queue_remove((Queue_Elem *)swi); if (fxn) { swi->fxn = fxn; } swi->posted = FALSE; 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->initTrigger = swi->trigger = params->trigger; swi->readyQ = Queue_Object_get(Swi_module->readyQ, swi->priority); Hwi_restore(hwiKey); }
/* * ======== Power_unregisterNotify ======== * Unregister for a power notification. * */ Power_Status Power_unregisterNotify(Power_NotifyHandle notifyHandle) { Power_Status status = Power_SOK; UInt key; /* check for NULL notifyHandle */ if (notifyHandle == NULL) { status = Power_EINVALIDHANDLE; } else { /* remove notify object from its event queue */ key = Hwi_disable(); Queue_remove((Queue_Elem *)notifyHandle); Hwi_restore(key); /* free the notify object */ Memory_free(Power_Object_heap(), notifyHandle, sizeof(Power_NotifyObj)); } return(status); }
/* * ======== Clock_removeI ======== */ Void Clock_removeI(Clock_Object *obj) { Queue_remove(&obj->elem); }
/* * ======== Task_Instance_finalize ======== */ Void Task_Instance_finalize(Task_Object *tsk, Int status) { #ifndef ti_sysbios_knl_Task_DISABLE_ALL_HOOKS Int i, cnt; #endif UInt taskKey, hwiKey; /* * Task's can only be deleted from main and task threads. * Running Tasks can not be deleted. */ if (status == 0) { taskKey = Task_disable(); /* * Bar users from calling Task_delete() on terminated tasks * if deleteTerminatedTasks is enabled. */ if ((Task_deleteTerminatedTasks == TRUE) && (Task_getMode(tsk) == Task_Mode_TERMINATED) && (tsk->readyQ == Task_Module_State_terminatedQ())) { Error_raise(NULL, Task_E_deleteNotAllowed, tsk, 0); } Assert_isTrue((Task_getMode(tsk) != Task_Mode_RUNNING), Task_A_badTaskState); Assert_isTrue((BIOS_getThreadType() == BIOS_ThreadType_Main) || (BIOS_getThreadType() == BIOS_ThreadType_Task), Task_A_badThreadType); hwiKey = Hwi_disable(); if (tsk->mode == Task_Mode_READY) { /* remove task from its ready list */ Queue_remove((Queue_Elem *)tsk); /* if last task in readyQ, remove corresponding bit in curSet */ if (Queue_empty(tsk->readyQ)) { Task_module->curSet &= ~tsk->mask; } /* * if task was made ready by a pend timeout but hasn't run yet * then its clock object is still on the Clock service Q. */ if (tsk->pendElem != NULL) { if (BIOS_clockEnabled && tsk->pendElem->clock) { Clock_removeI(tsk->pendElem->clock); } } } if (tsk->mode == Task_Mode_BLOCKED) { Assert_isTrue(tsk->pendElem != NULL, Task_A_noPendElem); /* Seemingly redundant test in case Asserts are disabled */ if (tsk->pendElem != NULL) { Queue_remove(&(tsk->pendElem->qElem)); if (BIOS_clockEnabled && tsk->pendElem->clock) { Clock_removeI(tsk->pendElem->clock); } } } if (tsk->mode == Task_Mode_TERMINATED) { /* remove task from terminated task list */ Queue_remove((Queue_Elem *)tsk); } else { Task_processVitalTaskFlag(tsk); } Hwi_restore(hwiKey); Task_restore(taskKey); } /* return if failed before allocating stack */ if (status == 1) { return; } if (BIOS_runtimeCreatesEnabled) { /* free stack if it was allocated dynamically */ if (tsk->stackHeap != (xdc_runtime_IHeap_Handle)(-1)) { Memory_free(tsk->stackHeap, tsk->stack, tsk->stackSize); } } /* return if failed to allocate Hook Env */ if (status == 2) { return; } /* status == 0 or status == 3 - in both cases create hook was called */ #ifndef ti_sysbios_knl_Task_DISABLE_ALL_HOOKS /* free any allocated Hook Envs */ if (Task_hooks.length > 0) { if (status == 0) { cnt = Task_hooks.length; } else { cnt = status - 3; /* # successful createFxn() calls */ } /* * only call deleteFxn() if createFxn() was successful */ for (i = 0; i < cnt; i++) { if (Task_hooks.elem[i].deleteFxn != NULL) { Task_hooks.elem[i].deleteFxn(tsk); } } Memory_free(Task_Object_heap(), tsk->hookEnv, Task_hooks.length * sizeof (Ptr)); } #endif }
/* * ======== Task_setPri ======== */ UInt Task_setPri(Task_Object *tsk, Int priority) { Int oldPri; UInt newMask, tskKey, hwiKey; Queue_Handle newQ; Assert_isTrue((((priority == -1) || (priority > 0) || ((priority == 0 && Task_module->idleTask == NULL))) && (priority < (Int)Task_numPriorities)), Task_A_badPriority); Log_write4(Task_LM_setPri, (UArg)tsk, (UArg)tsk->fxn, (UArg)tsk->priority, (UArg)priority); tskKey = Task_disable(); hwiKey = Hwi_disable(); oldPri = tsk->priority; if (oldPri == priority) { Hwi_restore(hwiKey); Task_restore(tskKey); return (oldPri); } if (priority < 0) { newMask = 0; newQ = Task_Module_State_inactiveQ(); } else { newMask = 1 << priority; newQ = (Queue_Handle)((UInt8 *)(Task_module->readyQ) + (UInt)(priority*(2*sizeof(Ptr)))); } if (tsk->mode == Task_Mode_READY) { Queue_remove((Queue_Elem *)tsk); /* if last task in readyQ, remove corresponding bit in curSet */ if (Queue_empty(tsk->readyQ)) { Task_module->curSet &= ~tsk->mask; } if (Task_module->curTask == tsk) { Task_module->curQ = newQ; /* force a Task_switch() */ /* if no longer maxQ */ /* Put current task at front of its new readyQ */ Queue_insert(((Queue_Elem *)(newQ))->next, (Queue_Elem *)tsk); } else { /* place task at end of its readyQ */ Queue_enqueue(newQ, (Queue_Elem *)tsk); } Task_module->curSet |= newMask; } tsk->priority = priority; tsk->mask = newMask; tsk->readyQ = newQ; if (priority < 0) { Task_module->curQ = NULL; /* force a Task_switch() */ } Task_module->workFlag = 1; Hwi_restore(hwiKey); Task_restore(tskKey); return oldPri; }
/* * ======== Task_Instance_finalize ======== * free stack if alloced during create */ Void Task_Instance_finalize(Task_Object *tsk, Int status) { Int i, cnt; /* * Task's can only be deleted from main and task threads. * Task's can only be deleted when they are in these states: * Task_Mode_TERMINATED * Task_Mode_READY */ if (status == 0) { Assert_isTrue((tsk->mode == Task_Mode_TERMINATED) || (tsk->mode == Task_Mode_BLOCKED) || ((tsk->mode == Task_Mode_READY) && (tsk != Task_self())), Task_A_badTaskState); Assert_isTrue((BIOS_getThreadType() == BIOS_ThreadType_Main) || (BIOS_getThreadType() == BIOS_ThreadType_Task), Task_A_badThreadType); if (tsk->mode == Task_Mode_READY) { /* remove task from its ready list */ Queue_remove((Queue_Elem *)tsk); /* if last task in readyQ, remove corresponding bit in curSet */ if (Queue_empty(tsk->readyQ)) { Task_module->curSet &= ~tsk->mask; } } if (tsk->mode == Task_Mode_BLOCKED) { Assert_isTrue(tsk->pendElem != NULL, Task_A_noPendElem); if (tsk->pendElem != NULL) { Queue_remove(&(tsk->pendElem->qElem)); if (tsk->pendElem->clock) { Clock_destruct(Clock_struct(tsk->pendElem->clock)); } } } if (tsk->mode == Task_Mode_TERMINATED) { /* remove task from terminated task list */ Queue_remove((Queue_Elem *)tsk); } } /* return if failed before allocating stack */ if (status == 1) { return; } /* free stack if it was allocated dynamically */ if (tsk->stackHeap != (xdc_runtime_IHeap_Handle)(-1)) { Memory_free(tsk->stackHeap, tsk->stack, tsk->stackSize); } /* return if failed to allocate Hook Env */ if (status == 2) { return; } /* status == 0 or status == 3 - in both cases create hook was called */ #ifndef ti_sysbios_knl_Task_DISABLE_ALL_HOOKS /* free any allocated Hook Envs */ if (Task_hooks.length > 0) { if (status == 0) { cnt = Task_hooks.length; } else { cnt = status - 3; /* # successful createFxn() calls */ } /* * only call deleteFxn() if createFxn() was successful */ for (i = 0; i < cnt; i++) { if (Task_hooks.elem[i].deleteFxn != NULL) { Task_hooks.elem[i].deleteFxn(tsk); } } Memory_free(Task_Object_heap(), tsk->hookEnv, Task_hooks.length * sizeof (Ptr)); } #endif }