⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 windlib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* windview - level 2 event logging */    EVT_TASK_1 (EVENT_WINDDELETE, (int) pTcb); 	/* log event */#endif    if (pTcb->status == WIND_READY)			/* if task is ready */	Q_REMOVE (&readyQHead, pTcb);			/* remove from queue */    else	{	if (pTcb->status & WIND_PEND)			/* if task is pended */            status = windPendQRemove (pTcb);            /* remove from queue */	if (pTcb->status & WIND_DELAY)			/* if task is delayed */	    Q_REMOVE (&tickQHead, &pTcb->tickNode);	/* remove from queue */	}    /* disconnect all the swap in hooks the task has connected to */    for (ix = 0, mask = pTcb->swapInMask; mask != 0; ix++, mask = mask << 1)	if (mask & 0x8000)	   taskSwapReference [ix] --;    /* disconnect all the swap out hooks the task has connected to */    for (ix = 0, mask = pTcb->swapOutMask; mask != 0; ix++, mask = mask << 1)	if (mask & 0x8000)	   taskSwapReference [ix] --;    Q_REMOVE (&activeQHead, &pTcb->activeNode);		/* deactivate it */    pTcb->status = WIND_DEAD;		       		/* kill it */    return (status);    }/********************************************************************************* windSuspend - suspend a task** Suspension is an additive state.  When a task is on the ready queue it* is removed and changed to suspended.  Otherwise, the status is updated* to include suspended in addition to the state it is already in.** NOMANUAL*/void windSuspend    (    FAST WIND_TCB *pTcb         /* address of task's tcb, 0 = current task */    )    {#ifdef WV_INSTRUMENTATION    /* windview - level 2 event logging */    EVT_TASK_1 (EVENT_WINDSUSPEND, (int) pTcb); 	/* log event */#endif    if (pTcb->status == WIND_READY)	Q_REMOVE (&readyQHead, pTcb);    pTcb->status |= WIND_SUSPEND;		/* update status */    }/********************************************************************************* windResume - resume a task** Resume the specified task and place in the ready queue if necessary.** NOMANUAL*/void windResume    (    FAST WIND_TCB *pTcb         /* task to resume */    )    {#ifdef WV_INSTRUMENTATION    /* windview - level 2 event logging */    EVT_TASK_1 (EVENT_WINDRESUME, (int) pTcb); 	/* log event */#endif    if (pTcb->status == WIND_SUSPEND)			/* just suspended so */	Q_PUT (&readyQHead, pTcb, pTcb->priority);	/* put in ready queue */    pTcb->status &= ~WIND_SUSPEND;		/* mask out the suspend state */    }/********************************************************************************* windPriNormalSet - set the normal priority of a task** Set the normal priority of a task.  A task will execute at its normal priority* as long as no priority inheritance has taken place.** NOMANUAL*/void windPriNormalSet    (    WIND_TCB    *pTcb,          /* address of task's tcb */    UINT         priNormal      /* new normal priority */    )    {    pTcb->priNormal = priNormal;	/* update normal priority */    windPrioritySet (pTcb, priNormal);	/* resort to appropriate priority */    }/********************************************************************************* windPrioritySet - resort the specified task to the appropriate priority** This routine sets the actual priority of task, taking into account priority* inversion safety.  If a task owns any priority inversion safety semaphores* then the priority will not be allowed to lower.** NOMANUAL*/void windPrioritySet    (    FAST WIND_TCB *pTcb,        /* address of task's tcb */    FAST UINT      priority     /* new priority */    )    {    /* if lowering the current priority and the task doesn't own any mutex     * semaphores with inheritance, then go ahead and lower current priority.     */    if ((pTcb->priMutexCnt == 0) && (pTcb->priority < priority))	{#ifdef WV_INSTRUMENTATION        /* windview - level 2 event logging */	EVT_TASK_3 (EVENT_WINDPRIORITYSETLOWER, (int) pTcb, 		pTcb->priority, priority);#endif	pTcb->priority = priority;		/* lower current priority */	if (pTcb->status == WIND_READY)		/* task is in ready Q? */	    {	    Q_RESORT (&readyQHead, pTcb, priority);	    }	else if (pTcb->status & WIND_PEND)	/* task is in pend Q? */	    {	    Q_RESORT (pTcb->pPendQ, pTcb, priority);	    }	return;					/* no inheritance if lowering */	}    while (pTcb->priority > priority)		/* current priority too low? */	{#ifdef WV_INSTRUMENTATION        /* windview - level 2 event logging */	EVT_TASK_3 (EVENT_WINDPRIORITYSETRAISE, (int) pTcb, 		pTcb->priority, priority);#endif	pTcb->priority = priority;		/* raise current priority */	if (pTcb->status == WIND_READY)		/* task is in ready Q? */	    {	    Q_RESORT (&readyQHead, pTcb, priority);	    }	else if (pTcb->status & WIND_PEND)	/* task is in pend Q? */	    {	    Q_RESORT (pTcb->pPendQ, pTcb, priority);	    if (pTcb->pPriMutex != NULL)	/* chain up for inheritance */		pTcb = pTcb->pPriMutex->semOwner;	    }	}    }/********************************************************************************* windSemDelete - delete a semaphore** Delete a semaphore and unblock any tasks pended on it.  Unblocked tasks* will be returned ERROR.** NOMANUAL*/void windSemDelete    (    FAST SEM_ID semId   /* semaphore to delete */    )    {    FAST WIND_TCB *pTcb;#ifdef WV_INSTRUMENTATION    /* windview - level 2 event logging */    EVT_TASK_1 (EVENT_WINDSEMDELETE, (int) semId);      /* log event */#endif    windPendQTerminate (&semId->qHead);			/* terminate pend q */    if ((semId->semType == SEM_TYPE_MUTEX) &&		/* mutex semaphore? */	((pTcb = semId->semOwner) != NULL) &&		/* is there an owner? */        (OBJ_VERIFY (&((WIND_TCB *)(pTcb))->objCore, taskClassId) == OK))	{	if ((semId->options & SEM_INVERSION_SAFE) &&	/* inversion safe opt?*/	    (-- pTcb->priMutexCnt == 0) && 		/* last mutex owned? */	    (pTcb->priority != pTcb->priNormal))	/* priority inherited?*/	    {	    windPrioritySet (pTcb, pTcb->priNormal);	/* back to normal pri */	    }	if ((semId->options & SEM_DELETE_SAFE) &&	/* deletion safe opt? */	    ((-- pTcb->safeCnt) == 0) &&		/* unsafe now? */	    (Q_FIRST (&pTcb->safetyQHead) != NULL))	/* deleters pended? */	    {	    windPendQFlush (&pTcb->safetyQHead); /* flush deleters */	    }	}    }/********************************************************************************* windTickAnnounce - acknowledge the passing of time** Process delay list.  Make tasks at the end of their delay, ready.* Perform round robin scheduling if selected.* Call any expired watchdog routines.** NOMANUAL*/void windTickAnnounce (void)    {    FAST Q_NODE *	pNode;	/* node of tick queue */    FAST WIND_TCB *	pTcb;	/* pointer to task control block */    FAST WDOG *		wdId;	/* pointer to a watchdog */    FUNCPTR		wdRtn;	/* watch dog routine to invoke */    int			wdArg;	/* watch dog argument to pass with wdRtn */    int 		status;	/* status return by Q_REMOVE */    /* advance and manage the tick queue */    vxTicks ++;						/* advance rel time */    vxAbsTicks++;					/* advance abs time */    Q_ADVANCE (&tickQHead);				/* advance tick queue */    while ((pNode = (Q_NODE *) Q_GET_EXPIRED (&tickQHead)) != NULL)	{	pTcb = (WIND_TCB *) ((int)pNode - OFFSET (WIND_TCB, tickNode));	if  (	    (pTcb->objCore.pObjClass == taskClassId)	/* is it a task? */#ifdef WV_INSTRUMENTATION 	    || (pTcb->objCore.pObjClass == taskInstClassId)#endif	    )	    { pTcb->status &= ~WIND_DELAY;		/* out of delay state */	    if (pTcb->status == WIND_READY)		/* taskDelay done */		{#ifdef WV_INSTRUMENTATION    		/* windview - level 2 event logging */		EVT_TASK_1 (EVENT_WINDTICKUNDELAY, (int) pTcb); #endif		taskRtnValueSet (pTcb, OK);		/* return OK */		}	    else if (pTcb->status & WIND_PEND)		/* semaphore timeout */		{                /*                 * if the task was pended on a shared semaphore                 * windPendQRemove can return :                 * ERROR if lock cannot be taken                 * ALREADY_REMOVED if the shared tcb is already removed                 * from the pend Q on the give side but has not                 * shows up on this side.                 */#ifdef WV_INSTRUMENTATION		 EVT_TASK_1 (EVENT_WINDTICKTIMEOUT, (int )pTcb); #endif                status = windPendQRemove (pTcb);        /* out of semaphore q */                switch (status)                    {                    case ALREADY_REMOVED:                        {                        /* the semaphore was given in time, return OK */                        taskRtnValueSet (pTcb, OK);                        break;                        }                    case ERROR:                        {                        taskRtnValueSet (pTcb, ERROR);      /* return ERROR */                        pTcb->errorStatus = S_smObjLib_LOCK_TIMEOUT;                        break;                        }                    default:                        {                        taskRtnValueSet (pTcb, ERROR);  /* return ERROR */                        pTcb->errorStatus = S_objLib_OBJ_TIMEOUT;                        }                    }		}	    if (pTcb->status == WIND_READY)		/* if ready, enqueue */		Q_PUT (&readyQHead, pTcb, pTcb->priority);	    }	else						/* must be a watchdog */	    {	    wdId = (WDOG *) ((int)pNode - OFFSET (WDOG, tickNode));#ifdef WV_INSTRUMENTATION    	    /* windview - level 2 event logging */	    EVT_TASK_1 (EVENT_WINDTICKANNOUNCETMRWD, (int) wdId);#endif	    wdId->status = WDOG_OUT_OF_Q;		/* mark as out of q */	    /* We get the watch dog routine and argument before testing	     * deferStartCnt to avoid having to lock interrupts.  The RACE	     * to worry about is a wdStart () or wdCancel () occuring after	     * the test of deferStartCnt and before invoking the routine.	     */	    wdRtn = wdId->wdRoutine;			/* get watch dog rtn */	    wdArg = wdId->wdParameter;			/* get watch dog arg */	    intCnt ++;                                  /* fake ISR context */	    if (wdId->deferStartCnt == 0)               /* check validity */		(* wdRtn) (wdArg);                      /* invoke wdog rtn */            intCnt --;                                  /* unfake ISR context */	    workQDoWork ();				/* do deferred work */	    }	}    /* perform round robin scheduling if selected */    if ((roundRobinOn) && (taskIdCurrent->lockCnt == 0) &&	(taskIdCurrent->status == WIND_READY) &&	(++ taskIdCurrent->tslice >= roundRobinSlice))	{#ifdef WV_INSTRUMENTATION    	/* windview - level 2 event logging */	EVT_TASK_0 (EVENT_WINDTICKANNOUNCETMRSLC);	/* log event */#endif	taskIdCurrent->tslice = 0;			/* reset time slice  */	Q_REMOVE (&readyQHead, taskIdCurrent);		/* no Q_RESORT here! */	Q_PUT (&readyQHead, taskIdCurrent, taskIdCurrent->priority);	}    }/********************************************************************************* windDelay - put running task asleep for specified ticks** Insert task in delay queue at correct spot dictated by the specified duration.** RETURNS: OK** NOMANUAL*/STATUS windDelay    (    FAST int timeout    )    {#ifdef WV_INSTRUMENTATION    /* windview - level 2 event logging */    EVT_TASK_1 (EVENT_WINDDELAY, timeout); 	/* log event */#endif    Q_REMOVE (&readyQHead, taskIdCurrent);		/* out of ready queue */    if ((unsigned)(vxTicks + timeout) < vxTicks)	/* rollover? */	{	Q_CALIBRATE (&tickQHead, ~vxTicks + 1);	vxTicks = 0;	}    Q_PUT (&tickQHead, &taskIdCurrent->tickNode, timeout + vxTicks);    taskIdCurrent->status |= WIND_DELAY;		/* set delay status */    return (OK);    }/********************************************************************************* windUndelay - wake a sleeping task up*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -