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

📄 semsmlib.c

📁 Vxworks 源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
** NOMANUAL*/STATUS semSmBInit    (    SM_SEMAPHORE * pSem,                /* pointer to semaphore to initialize */    int            options,             /* semaphore options */    SEM_B_STATE    initialState         /* initial semaphore state */    )    {    Q_FIFO_G_HEAD           pseudoPendQ; /* pseudo pendQ to init sem pend Q */    SM_SEMAPHORE volatile * pSemv = (SM_SEMAPHORE volatile *) pSem;    int                     temp;        /* temp storage */    if (!semSmLibInstalled)        {	semSmLibInit ();		/* initialize package */        }    if (options != SEM_Q_FIFO)		/* only FIFO queuing for now */	{	errno = S_semLib_INVALID_QUEUE_TYPE;	return (ERROR);	}    pSemv->objType = htonl (SEM_TYPE_SM_BINARY); /* semaphore type is binary */    pSemv->lock    = 0;				/* lock available */    /* initialize pseudo multi way queue */    pseudoPendQ.pLock   = NULL;			/* we already have the lock */    pseudoPendQ.pFifoQ  = &pSem->smPendQ;	/* address of actual queue */    pseudoPendQ.pQClass = qFifoGClassId;	/* global fifo multi way Q */    qFifoGInit (&pseudoPendQ);         		/* initialize sem pend Q */    /* fill state flag according to initial state */    switch (initialState)        {        case SEM_EMPTY:        case SEM_FULL:            pSemv->state.flag = htonl (initialState);               break;        default:            errno = S_semLib_INVALID_STATE;            return (ERROR);        }    /* verify field must contain the global address of semaphore */    pSemv->verify = (UINT32) htonl (LOC_TO_GLOB_ADRS (pSem));	    CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */    temp = pSemv->lock;                         /* BRIDGE FLUSH  [SPR 68334] */    return (OK);    }/******************************************************************************* semCSmCreate - create and initialize a shared memory counting semaphore (VxMP Option)** This routine allocates and initializes a shared memory counting* semaphore.  The initial count value of the semaphore is specified* by <initialCount>.** The semaphore ID returned by this routine can be used directly by the* generic semaphore-handling routines in semLib -- semGive(), semTake() and* semFlush() -- and the show routines, such as show() and semShow().** The queuing style for blocked tasks is set by <options>; the only* supported queuing style for shared memory semaphores is first-in-first-out,* selected by SEM_Q_FIFO .** Before this routine can be called, the shared memory objects facility must* be initialized (see semSmLib).** The maximum number of shared memory semaphores (binary plus counting) that* can be created is SM_OBJ_MAX_SEM , a configurable paramter.** AVAILABILITY* This routine is distributed as a component of the unbundled shared memory* support option, VxMP.* * RETURNS: The semaphore ID, or NULL if memory cannot be allocated* from the shared semaphore dedicated memory partition.** ERRNO: S_memLib_NOT_ENOUGH_MEMORY, S_semLib_INVALID_QUEUE_TYPE,* S_smObjLib_LOCK_TIMEOUT** SEE ALSO: semLib, semCLib, smObjLib, semShow,* \tb VxWorks Programmer's Guide: Basic OS** INTERNAL* The least significant bit of the semaphore ID is set to 1 in order to* differentiate shared and local semaphores.*/SEM_ID semCSmCreate    (    int options,	/* semaphore options */    int initialCount	/* initial semaphore count */    )    {    SM_SEM_ID smSemId;    int       temp;     /* temp storage */    /* allocate semaphore structure from shared semaphore dedicated pool */    smSemId = (SM_SEM_ID) smMemPartAlloc ((SM_PART_ID) smSemPartId,                                          sizeof (SM_SEMAPHORE));    if (smSemId == NULL)        {	return (NULL);        }    bzero ((char *) smSemId, sizeof(SM_SEMAPHORE));    /* initialize allocated semaphore */    if (semSmCInit ((SM_SEMAPHORE *) (smSemId), options, initialCount) != OK)        {        smMemPartFree ((SM_PART_ID) smSemPartId, (char *) smSemId);        return (NULL);        }    /* update shared memory objects statistics */    CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */    temp = pSmObjHdr->curNumSemC;               /* PCI bridge bug [SPR 68844]*/    pSmObjHdr->curNumSemC = htonl (ntohl (pSmObjHdr->curNumSemC) + 1);    CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */    temp = pSmObjHdr->curNumSemC;               /* BRIDGE FLUSH  [SPR 68334] */    return ((SEM_ID) (SM_OBJ_ADRS_TO_ID (smSemId)));    }/******************************************************************************* semSmCInit - initialize a declared shared counting semaphore** The initialization of a static counting semaphore, or a shared * counting semaphore embedded in some larger object need not deal * with allocation.* This routine may be called to initialize such a semaphore.  The semaphore* <pSem> is initialized to the specified <initialCount>.** Counting semaphore <options> include the queuing style for blocked tasks.* The only available pending queue type is first-in-first-out, type* SEM_Q_FIFO defined as 0 in semLib.h.** The semaphore address parameter <pSem> is the local address of a* shared semaphore data structure.** RETURNS: OK or ERROR if queue type invalid.** ERRNO: S_semLib_INVALID_QUEUE_TYPE** SEE ALSO: semCSmCreate()** NOMANUAL*/STATUS semSmCInit    (    SM_SEMAPHORE * pSem,                /* pointer to semaphore to initialize */    int            options,             /* semaphore options */    int            initialCount         /* initial semaphore count */    )    {    Q_FIFO_G_HEAD           pseudoPendQ; /* pseudo pendQ to init sem pend Q */    SM_SEMAPHORE volatile * pSemv = (SM_SEMAPHORE volatile *) pSem;    int                     temp;        /* temp storage */    if (!semSmLibInstalled)        {        semSmLibInit ();                /* initialize package */        }    if (options != SEM_Q_FIFO)          /* only FIFO queuing for now */        {        errno = S_semLib_INVALID_QUEUE_TYPE;        return (ERROR);        }    pSemv->objType = htonl(SEM_TYPE_SM_COUNTING);/* fill semaphore type */    pSemv->lock    = 0;				/* lock available */    /* initialize pseudo multi way queue */    pseudoPendQ.pLock   = NULL;			/* we already have the lock */    pseudoPendQ.pFifoQ  = &pSem->smPendQ;	/* address of actual queue */    pseudoPendQ.pQClass = qFifoGClassId;	/* global fifo multi way Q */    qFifoGInit (&pseudoPendQ);         		/* initialize sem pend Q */    pSemv->state.count = htonl (initialCount); 	/* set initial count */    /* verify field must contain the global address of semaphore */    pSemv->verify = (UINT32) htonl (LOC_TO_GLOB_ADRS (pSem));    CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */    temp = pSemv->lock;                         /* BRIDGE FLUSH  [SPR 68334] */    return (OK);    }/******************************************************************************* semSmGive - give shared memory binary or counting 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.  If that task is local to this CPU and is of* higher priority than the task that does the semGive, it will preempt this* task.  If the first pended task is located on a remote processor, the* availability of the semaphore is made known to the remote processor via* an internal notification mecanism.* * For a shared binary semaphore, if the semaphore is already full (it has* been given but not taken), this call is essentially a no-op.** For a shared counting semaphore, if the semaphore count is already* greater than 0 (semaphore was given but not taken), this call is* essentially a no-op.** The <smSemId> passed to this routine must be the local semaphore address.** This routine is usually called by semGive() which first converts the* semaphore ID to the shared semaphore local address.** WARNING* This routine may not be used from interrupt level.** RETURNS: OK or ERROR.** ERRNO: S_intLib_NOT_ISR_CALLABLE, S_objLib_OBJ_ID_ERROR,*        S_smObjLib_LOCK_TIMEOUT** NOMANUAL*/STATUS semSmGive    (    SM_SEM_ID smSemId           /* global semaphore ID to give */    )    {    Q_FIFO_G_HEAD pendQ;        /* temporary pendQ to unpend task */    int           level;	/* processor specific inLock return value */    SM_DL_LIST    eventList;	/* list of events used to notify give */    SM_OBJ_TCB volatile *  firstSmTcb;   /* first pending shared memory tcb */    SM_SEM_ID volatile     smSemIdv = (SM_SEM_ID volatile) smSemId;    int                    temp;         /* temp storage */        if (INT_RESTRICT () != OK)		/* not ISR callable */        {	return (ERROR);        }    CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */    temp = smSemIdv->verify;                    /* PCI bridge bug [SPR 68844]*/    if (SM_OBJ_VERIFY (smSemIdv) != OK)	/* check semaphore id */	{	return (ERROR);	}    /* ENTER LOCKED SECTION */    if (SM_OBJ_LOCK_TAKE (&smSemId->lock, &level) != OK) 	{	smObjTimeoutLogMsg ("semGive", (char *) &smSemId->lock);	return (ERROR);                         /* can't take lock */	}    /* get first pending shared TCB */    firstSmTcb = (SM_OBJ_TCB volatile *) SM_DL_FIRST (&smSemId->smPendQ);    /* pendQ is empty */    if (firstSmTcb == (SM_OBJ_TCB volatile *) LOC_NULL)	{        /* binary semaphore: sem available */	if (ntohl (smSemIdv->objType) == SEM_TYPE_SM_BINARY) 	    {	    smSemIdv->state.flag = htonl (SEM_FULL);	    }        /* counting semaphore: increment sem count */        else	    {	    smSemIdv->state.count = htonl (ntohl (smSemIdv->state.count) + 1);	    }        /* EXIT LOCKED SECTION */	SM_OBJ_LOCK_GIVE (&smSemId->lock, level);	return (OK);	}    /* pendQ is not empty, initialize pseudo multi way queue */    pendQ.pLock   = NULL;			/* we already have the lock */    pendQ.pFifoQ  = &smSemId->smPendQ;	 	/* address of actual queue */    pendQ.pQClass = qFifoGClassId;		/* global fifo multi way Q */    /*      * Do now the necessary manipulations in shared memory     * in order to be able to release lock access ASAP     * thus reducing interrupt latency.     */    /* ENTER KERNEL */    kernelState = TRUE;    /* remove from pending list */    Q_REMOVE (&pendQ, (SM_DL_NODE *) firstSmTcb);    /* EXIT LOCKED SECTION */    SM_OBJ_LOCK_GIVE (&smSemId->lock, level);    /* pending task is local */    if (ntohl (firstSmTcb->ownerCpu) == smObjProcNum)	{	/* 	 * The shared TCB has been removed from the shared semaphore	 * pendQ by qFifoGRemove(), during that call removedByGive is	 * set to TRUE to avoid non-null notification time race.	 * Then, if the task that has taken the semaphore is remote,	 * an event notification is done and removedByGive is reset	 * by smObjEventProcess() on the remote processor.	 * If the pended task is local removedByGive must be reset	 * here to avoid the shared TCB being screwed up.	 */ 	firstSmTcb->removedByGive = htonl (FALSE);	/* windview - level 2 event logging */	EVT_TASK_1 (EVENT_OBJ_SEMGIVE, smSemId);        CACHE_PIPE_FLUSH ();                    /* CACHE FLUSH   [SPR 68334] */        temp = (int) firstSmTcb->localTcb;      /* PCI bridge bug [SPR 68844]*/	windReadyQPut ((WIND_TCB *) ntohl ((int) firstSmTcb->localTcb));	}

⌨️ 快捷键说明

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