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

📄 semblib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    }/********************************************************************************* semBInit - initialize a declared binary semaphore** The initialization of a static binary semaphore, or a binary semaphore* embedded in some larger object need not deal with allocation.* This routine may be called to initialize such a semaphore.  The semaphore* is initialized to the specified initial state of either SEM_FULL or SEM_EMPTY.** Binary semaphore options include the queuing style for blocked tasks.* Tasks can be queued on the basis of their priority or first-in-first-out.* These options are SEM_Q_PRIORITY and SEM_Q_FIFO respectively.** SEE ALSO: semBCreate()** NOMANUAL*/STATUS semBInit    (    SEMAPHORE  *pSemaphore,             /* pointer to semaphore to initialize */    int         options,                /* semaphore options */    SEM_B_STATE initialState            /* initial semaphore state */    )    {    if ((!semBLibInstalled) && (semBLibInit () != OK))	/* initialize package */	return (ERROR);    if (semQInit (pSemaphore, options) != OK)		/* initialize queue */	return (ERROR);    return (semBCoreInit (pSemaphore, options, initialState));    }/********************************************************************************* semBCoreInit - initialize a binary semaphore with queue already initialized** To initialize a semaphore with some special queuing algorithm, this routine* is used.  This routine will initialize a binary semaphore without* initializing the queue.** ERRNO: S_semLib_INVALID_OPTION, S_semLib_INVALID_STATE** NOMANUAL*/STATUS semBCoreInit    (    SEMAPHORE  *pSemaphore,             /* pointer to semaphore to initialize */    int         options,                /* semaphore options */    SEM_B_STATE initialState            /* initial semaphore state */    )    {    if ((options & SEM_INVERSION_SAFE) || (options & SEM_DELETE_SAFE))	{	errno = S_semLib_INVALID_OPTION;	return (ERROR);	}    switch (initialState)	{	case SEM_EMPTY:	    pSemaphore->semOwner = taskIdCurrent;	/* semaphore empty */	    break;	case SEM_FULL:	    pSemaphore->semOwner = NULL;		/* semaphore full */	    break;	default:	    errno = S_semLib_INVALID_STATE;	    return (ERROR);	}    pSemaphore->recurse = 0;				/* no recursive takes */    pSemaphore->options = options;			/* stow away options */    pSemaphore->semType = SEM_TYPE_BINARY;		/* type is binary */    eventInit (&pSemaphore->events);			/* initialize events */#ifdef WV_INSTRUMENTATION    /* windview - connect instrumented class for level 1 event logging */    if (wvObjIsEnabled)        objCoreInit (&pSemaphore->objCore, semInstClassId);    else #endif    objCoreInit (&pSemaphore->objCore, semClassId); /* initialize core */    return (OK);    }#ifdef semBLib_PORTABLE/********************************************************************************* semBGive - give semaphore** Gives the semaphore.  If a higher priority task has already taken* the semaphore (so that it is now pended waiting for it), that task* will now become ready to run, and preempt the task that does the semGive().* If the semaphore is already full (it has been given but not taken) this* call is essentially a no-op.** NOMANUAL*/STATUS semBGive    (    SEM_ID semId        /* semaphore ID to give */    )    {    int level = intLock ();			/* LOCK INTERRUPTS */    WIND_TCB * pOwner;    if (OBJ_VERIFY (semId, semClassId) != OK)	{	intUnlock (level);			/* UNLOCK INTERRUPTS */	return (ERROR);	}    pOwner = semId->semOwner;    if ((semId->semOwner = (WIND_TCB *) Q_FIRST (&semId->qHead)) == NULL)	{	int    	oldErrno;	STATUS  evStatus;	STATUS 	retStatus;	retStatus = OK;	/* check change of state; if so, send events */	if ((semId->events.taskId != (int)NULL) && (pOwner != NULL))	    {	    kernelState = TRUE;	    intUnlock (level);			/* UNLOCK INTERRUPTS */	    oldErrno = errno;	    evStatus = eventRsrcSend(semId->events.taskId,				     semId->events.registered);	    if (evStatus != OK)		{		if ((semId->options & SEM_EVENTSEND_ERR_NOTIFY) != 0x0)		    {		    retStatus = ERROR;		    oldErrno = S_eventLib_EVENTSEND_FAILED;		    }		semId->events.taskId = (int)NULL;		}	    else if ((semId->events.options & EVENTS_SEND_ONCE) != 0x0)		semId->events.taskId = (int)NULL;	    windExit ();	    errno = oldErrno;	    return (retStatus);	    }	else	    intUnlock (level);	}    else	{	kernelState = TRUE;			/* KERNEL ENTER */ 	intUnlock (level);			/* UNLOCK INTERRUPTS */#ifdef WV_INSTRUMENTATION	/* windview - level 2 event logging */	EVT_TASK_1 (EVENT_OBJ_SEMGIVE, semId);#endif	windPendQGet (&semId->qHead);		/* unblock a task */	windExit ();				/* KERNEL EXIT */	}    return (OK);    }/********************************************************************************* semBTake - take semaphore** Takes the semaphore.  If the semaphore is empty, i.e., it has not been given* since the last semTake() or semInit(), this task will become pended until* the semaphore becomes available by some other task doing a semGive()* of it.  If the semaphore is already available, this call will empty* the semaphore, so that no other task can take it until this task gives* it back, and this task will continue running.** WARNING* This routine may not be used from interrupt level.** NOMANUAL*/STATUS semBTake    (    SEM_ID semId,       /* semaphore ID to take */    int timeout         /* timeout in ticks */    )    {    int level;    int status;    if (INT_RESTRICT () != OK)	return (ERROR);again:    level = intLock ();				/* LOCK INTERRUPTS */    if (OBJ_VERIFY (semId, semClassId) != OK)	{	intUnlock (level);			/* UNLOCK INTERRUPTS */	return (ERROR);	}    if (semId->semOwner == NULL)	{	semId->semOwner = taskIdCurrent;	/* update semaphore state */	intUnlock (level);			/* UNLOCK INTERRUPTS */	return (OK);	}    kernelState = TRUE;				/* KERNEL ENTER */    intUnlock (level);				/* UNLOCK INTERRUPTS */#ifdef WV_INSTRUMENTATION    /* windview - level 2 event logging */    EVT_TASK_1 (EVENT_OBJ_SEMTAKE, semId);#endif    if (windPendQPut (&semId->qHead, timeout) != OK)	{	windExit ();				/* KERNEL EXIT */	return (ERROR);	}    if ((status = windExit ()) == RESTART)	/* KERNEL EXIT */	{	timeout = SIG_TIMEOUT_RECALC(timeout);	goto again;	}    return (status);    }#endif	/* semBLib_PORTABLE *//********************************************************************************* semBGiveDefer - give semaphore as deferred work** Gives the semaphore.  If a higher priority task has already taken* the semaphore (so that it is now pended waiting for it), that task* will now become ready to run, and preempt the task that does the semGive().* If the semaphore is already full (it has been given but not taken) this* call is essentially a no-op.** NOMANUAL*/void semBGiveDefer    ( SEM_ID semId        /* semaphore ID to give */    )    {    WIND_TCB * pOwner = semId->semOwner;    if ((semId->semOwner = (WIND_TCB *) Q_FIRST (&semId->qHead)) != NULL)	{#ifdef WV_INSTRUMENTATION    	/* windview - level 2 event logging */	EVT_TASK_1 (EVENT_OBJ_SEMGIVE, semId);#endif	windPendQGet (&semId->qHead);		/* unblock a task */	}    else /* check for change of state, send events if registered */	{	if ((semId->events.taskId != (int)NULL) && (pOwner != NULL))	    {	    if (eventRsrcSend(semId->events.taskId,			      semId->events.registered) != OK)		{		semId->events.taskId = (int)NULL;		}	    else if ((semId->events.options & EVENTS_SEND_ONCE) != 0x0 )		semId->events.taskId = (int)NULL;	    }	}    }

⌨️ 快捷键说明

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