StatusType ReleaseResource( ResourceType ResID) { StatusType rv = E_OK; OsTaskVarType *pcbPtr = Os_SysTaskGetCurr(); OsResourceType *rPtr; uint32_t flags; Irq_Save(flags); if( ResID == RES_SCHEDULER ) { rPtr = &Os_Sys.resScheduler; } else { /* Check we can access it */ if( (pcbPtr->constPtr->resourceAccess & (1<< ResID)) == 0 ) { rv = E_OS_ID; goto err; } rPtr = Os_ResourceGet(ResID); } /* Check for invalid configuration */ if( rPtr->owner == NO_TASK_OWNER) { rv = E_OS_NOFUNC; Irq_Restore(flags); goto err; } if( (pcbPtr->activePriority < rPtr->ceiling_priority)) { rv = E_OS_ACCESS; Irq_Restore(flags); goto err; } Os_TaskResourceRemove(rPtr,pcbPtr); /* do a rescheduling (in some cases) (see OSEK OS 4.6.1) */ if ( (pcbPtr->constPtr->scheduling == FULL) && (Os_Sys.intNestCnt == 0) && (Os_SchedulerResourceIsFree()) ) { OsTaskVarType* top_pcb = Os_TaskGetTop(); /* only dispatch if some other ready task has higher prio */ if (top_pcb->activePriority > Os_SysTaskGetCurr()->activePriority) { Os_Dispatch(OP_RELEASE_RESOURCE); } } Irq_Restore(flags); OS_STD_END_1(OSServiceId_ReleaseResource,ResID); }
/** * The events of the extended task calling ClearEvent are cleared * according to the event mask <Mask>. * * * @param Mask * @return */ StatusType ClearEvent( EventMaskType Mask) { StatusType rv = E_OK; OsTaskVarType *pcb = Os_SysTaskGetCurr(); imask_t flags; OS_VALIDATE( OS_SYS_PTR->intNestCnt == 0,E_OS_CALLEVEL); OS_VALIDATE(pcb->constPtr->proc_type == PROC_EXTENDED,E_OS_ACCESS); Irq_Save(flags); pcb->ev_set &= ~Mask; Irq_Restore(flags); if (0) goto err; OS_STD_END_1(OSServiceId_ClearEvent,Mask); }
StatusType WaitEvent( EventMaskType Mask ) { OsTaskVarType *curr_pcb = Os_SysTaskGetCurr(); StatusType rv = E_OK; imask_t state; OS_DEBUG(D_EVENT,"# WaitEvent %s\n",Os_SysTaskGetCurr()->constPtr->name); OS_VALIDATE( OS_SYS_PTR->intNestCnt == 0, E_OS_CALLEVEL); OS_VALIDATE( curr_pcb->constPtr->proc_type == PROC_EXTENDED,E_OS_ACCESS); OS_VALIDATE( !Os_TaskOccupiesResources(curr_pcb),E_OS_RESOURCE); #if (OS_NUM_CORES > 1) OS_VALIDATE( !Os_TaskOccupiesSpinlocks(curr_pcb) != 0,E_OS_SPINLOCK); /* @req 4.1.2/SWS_Os_00622 */ #endif /* Remove from ready queue */ Irq_Save(state); // OSEK/VDX footnote 5. The call of WaitEvent does not lead to a waiting state if one of the events passed in the event mask to // WaitEvent is already set. In this case WaitEvent does not lead to a rescheduling. if( !(curr_pcb->ev_set & Mask) ) { curr_pcb->ev_wait = Mask; if ( Os_SchedulerResourceIsFree() ) { // Os_TaskMakeWaiting(currTaskPtr); Os_Dispatch(OP_WAIT_EVENT); assert( curr_pcb->state & ST_RUNNING ); } else { Os_TaskMakeWaiting(curr_pcb); } } Irq_Restore(state); // The following line disables the unused label warning. Remove when // proper error handling is implemented. if (0) goto err; OS_STD_END_1(OSServiceId_WaitEvent,Mask); }
StatusType GetResource( ResourceType ResID ) { StatusType rv = E_OK; OsResourceType *rPtr; uint32_t flags; #if (OS_APPLICATION_CNT > 1) if (ResID != RES_SCHEDULER) { rv = Os_ApplHaveAccess( Os_ResourceGet(ResID)->accessingApplMask ); if( rv != E_OK ) { goto err; } } #endif Irq_Save(flags); if( Os_Sys.intNestCnt != 0 ) { /* For interrupts to the scheduler resource seems just dumb to get */ OsIsrVarType *isrPtr = Os_SysIsrGetCurr(); /* Check we can access it */ if( ((isrPtr->constPtr->resourceMask & (1<< ResID)) == 0) || ( ResID == RES_SCHEDULER ) ) { rv = E_OS_ID; goto err; } rPtr = Os_ResourceGet(ResID); /* ceiling prio for ISR seems strange...so no */ if( rPtr->owner != NO_TASK_OWNER ) { rv = E_OS_ACCESS; Irq_Restore(flags); goto err; } /* Add the resource to the list of resources held by this isr */ Os_IsrResourceAdd(rPtr,isrPtr); } else { OsTaskVarType *taskPtr = Os_SysTaskGetCurr(); if( ResID == RES_SCHEDULER ) { rPtr = &Os_Sys.resScheduler; } else { /* Check we can access it */ if( (taskPtr->constPtr->resourceAccess & (1<< ResID)) == 0 ) { rv = E_OS_ID; goto err; } rPtr = Os_ResourceGet(ResID); } /* Check for invalid configuration */ if( (rPtr->owner != NO_TASK_OWNER) || (taskPtr->activePriority > rPtr->ceiling_priority) ) { rv = E_OS_ACCESS; Irq_Restore(flags); goto err; } /* Add the resource to the list of resources held by this task */ Os_TaskResourceAdd(rPtr,taskPtr); } Irq_Restore(flags); if (rv != E_OK) goto err; OS_STD_END_1(OSServiceId_GetResource,ResID); }