예제 #1
0
파일: semaphore.c 프로젝트: idmond/moped
/**
 * Increase the semaphore value by 1. If
 *
 * @param semPtr
 */
void SignalSemaphore( OsSemaphoreType *semPtr ) {
    uint32_t flags;
    OsTaskVarType *taskPtr;

    Irq_Save(flags);

    assert( semPtr != NULL );

    ++semPtr->val;

    /* Remove the first task that waits at the semaphore */
    if( semPtr->val <= 0 ) {

        taskPtr = STAILQ_FIRST(&semPtr->taskHead);
        /* Make the first task ready */
        Os_TaskMakeReady(taskPtr);

        /* Release the first task in queue */
        STAILQ_REMOVE_HEAD(&semPtr->taskHead,semEntry);

        if( taskPtr->activePriority > Os_SysTaskGetCurr()->activePriority ) {
            Os_Dispatch(OP_SIGNAL_SEMAPHORE);
        }
    }

    Irq_Restore(flags);
}
예제 #2
0
StatusType SetEvent( TaskType TaskID, EventMaskType Mask ) {
	StatusType rv = E_OK;
	OsTaskVarType *destPcbPtr;
	OsTaskVarType *currPcbPtr;
	uint32_t flags;

	OS_DEBUG(D_EVENT,"# SetEvent %s\n",Os_SysTaskGetCurr()->constPtr->name);

	TASK_CHECK_ID(TaskID);

	destPcbPtr = Os_TaskGet(TaskID);
	currPcbPtr = Os_SysTaskGetCurr();

#if (OS_SC3==STD_ON) || (OS_SC4==STD_ON)

	if( destPcbPtr->constPtr->applOwnerId != OS_SYS_PTR->currApplId ) {
		ApplicationType appId;
	    APPL_CHECK_STATE(destPcbPtr->constPtr->applOwnerId);
    	/* Do we have access to the task we are activating */
        if(OS_SYS_PTR->intNestCnt == 0 ) {
        	appId = currPcbPtr->constPtr->applOwnerId;
        } else {
        	appId = Os_SysIsrGetCurr()->constPtr->appOwner;
        }

        APPL_CHECK_ACCESS( appId , destPcbPtr->constPtr->accessingApplMask);

#if (OS_NUM_CORES > 1)
	    if (Os_ApplGetCore(destPcbPtr->constPtr->applOwnerId) != GetCoreID()) {
	                StatusType status = Os_NotifyCore(Os_ApplGetCore(destPcbPtr->constPtr->applOwnerId),
	                                                  OSServiceId_SetEvent,
	                                                  TaskID,
	                                                  Mask,
	                                                  0);
	                return status;
#endif

	}
#endif

	OS_VALIDATE( destPcbPtr->constPtr->proc_type == PROC_EXTENDED, E_OS_ACCESS );
	OS_VALIDATE( !(destPcbPtr->state & ST_SUSPENDED ), E_OS_STATE);

	Irq_Save(flags);

	/* Calling  SetEvent  causes  the  task  <TaskID>  to be  transferred
	 * to  the  ready  state,  if  it  was  waiting  for  at  least one of the
	 * events specified in <Mask>.
	 *
	 * OSEK/VDX 4.6.1,  rescheduling is performed in all of the following cases:
	 * ..
	 * Setting an event to a waiting task at task level (e.g. system service SetEvent,
	 * see chapter 13.5.3.1, message notification mechanism, alarm expiration, if event setting
	 * defined, see chapter 9.2)
	 * ... */

	destPcbPtr->ev_set |= Mask;

	if( (Mask & destPcbPtr->ev_wait) ) {
		/* We have an event match */
		if( destPcbPtr->state & ST_WAITING) {
			Os_TaskMakeReady(destPcbPtr);

			currPcbPtr = Os_SysTaskGetCurr();
			/* Checking "4.6.2  Non preemptive scheduling" it does not dispatch if NON  */
			if( (OS_SYS_PTR->intNestCnt == 0) &&
				(currPcbPtr->constPtr->scheduling == FULL) &&
				(destPcbPtr->activePriority > currPcbPtr->activePriority) &&
				(Os_SchedulerResourceIsFree()) )
			{
				Os_Dispatch(OP_SET_EVENT);
			}

		}  else if(destPcbPtr->state & (ST_READY|ST_RUNNING|ST_SLEEPING) ) {
			/* Hmm, we do nothing */
		} else {
			assert( 0 );
		}
	}

	Irq_Restore(flags);

	OS_STD_END_2(OSServiceId_SetEvent,TaskID, Mask);
}


/**
 * This service returns the current state of all event bits of the task
 * <TaskID>, not the events that the task is waiting for.
 * The service may be called from interrupt service routines, task
 * level and some hook routines (see Figure 12-1).
 *  The current status of the event mask of task <TaskID> is copied
 * to <Event>.
 *
 * @param TaskId Task whose event mask is to be returned.
 * @param Mask   Reference to the memory of the return data.
 * @return
 */
StatusType GetEvent( TaskType TaskId, EventMaskRefType Mask) {

	OsTaskVarType *destPcbPtr;
	StatusType rv = E_OK;

	TASK_CHECK_ID(TaskId);

	destPcbPtr = Os_TaskGet(TaskId);

	OS_VALIDATE( (destPcbPtr->constPtr->proc_type == PROC_EXTENDED) ,E_OS_ACCESS);
	OS_VALIDATE( !(destPcbPtr->state & ST_SUSPENDED),E_OS_STATE);

	*Mask = destPcbPtr->ev_set;

	if (0) goto err;

	OS_STD_END_2(OSServiceId_GetEvent,TaskId, Mask);
}