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

📄 smobjlib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
** This routine will complete the attach process only if and when the shared* memory has been initialized by the master CPU.  If the shared memory is* not recognized as active within the timeout period (10 minutes), this* routine returns ERROR.** The smObjAttach() routine connects the shared memory objects handler to the* shared memory interrupt.  Note that this interrupt may be shared between* the shared memory network driver and the shared memory objects facility* when both are used at the same time.** WARNING:* Once a CPU has attached itself to the shared memory objects facility, * it cannot be detached.  Since the shared memory network driver and * the shared memory objects facility use the same low-level attaching* mechanism, a CPU cannot be detached from a shared memory network driver* if the CPU also uses shared memory objects.** AVAILABILITY* This routine is distributed as a component of the unbundled shared memory* objects support option, VxMP.* * RETURNS:* OK, or ERROR if the shared memory objects facility is not active* or the number of CPUs exceeds the maximum.** ERRNO:*  S_smLib_INVALID_CPU_NUMBER** SEE ALSO: smObjSetup(), smObjInit()*/STATUS smObjAttach    (    SM_OBJ_DESC * pSmObjDesc	/* pointer to shared memory descriptor */    )    {    SM_OBJ_CPU_INFO * pSmObjCpuInfo; /* cpu info structure to fill */    SM_OBJ_CPU_DESC * pObjDesc;      /* pointer to smObj CPU descriptor */    SM_ANCHOR *       pAnchor;       /* pointer to shared memory anchor */    int               cpuNum;        /* this CPU number */    int               beatsToWait;   /* heart beat period */    int               tmp;           /* temp storage */    cpuNum  = pSmObjDesc->smDesc.cpuNum;    pAnchor = pSmObjDesc->smDesc.anchorLocalAdrs;    /* Check that shared memory is initialized and running */    beatsToWait = (cpuNum == SM_MASTER) ?                  DEFAULT_BEATS_TO_WAIT : DEFAULT_ALIVE_TIMEOUT;    if (smIsAlive (pAnchor, &(pAnchor->smObjHeader), pSmObjDesc->smDesc.base,		   beatsToWait, pSmObjDesc->smDesc.ticksPerBeat) == FALSE)        {        return (ERROR);                         /* sh memory not active */        }    /* generic shared memory attach */    if (smAttach (&pSmObjDesc->smDesc) == ERROR)        {        return (ERROR);        }     /* set offset to access shared objects */    localToGlobalOffset = (int) pSmObjDesc->smDesc.anchorLocalAdrs;			      smObjPoolMinusOne = localToGlobalOffset - 1;    /* get local address of shared memory header */    pSmObjHdr = (SM_OBJ_MEM_HDR volatile *) GLOB_TO_LOC_ADRS(\                                                  ntohl(pAnchor->smObjHeader));    pSmObjDesc->hdrLocalAdrs = (SM_OBJ_MEM_HDR *) pSmObjHdr;    pSmObjDesc->cpuLocalAdrs = (SM_OBJ_CPU_DESC *)                                GLOB_TO_LOC_ADRS (ntohl (pSmObjHdr->objCpuTbl));    /* initialize shared TCB partition id and free routines pointer */         smTcbPartId = (SM_FIX_BLK_PART_ID)		   (LOC_TO_GLOB_ADRS((&pSmObjHdr->smTcbPart)));    smObjTcbFreeRtn        = (FUNCPTR) smObjTcbFree;    smObjTcbFreeFailRtn    = (FUNCPTR) smObjTcbFreeLogMsg;    /* set global name database pointer */    pSmNameDb = &pSmObjHdr->nameDtb;   /* get name database header */    /* initialize windDelete failure notification routine pointer */    smObjTaskDeleteFailRtn = (FUNCPTR) smObjTimeoutLogMsg;    /* get local event Q pointer */    pSmObjCpuInfo = (SM_OBJ_CPU_INFO *) malloc (sizeof (SM_OBJ_CPU_INFO));    bzero ((char *) pSmObjCpuInfo, sizeof (SM_OBJ_CPU_INFO));    smObjCpuInfoGet (pSmObjDesc, NONE, pSmObjCpuInfo);    pLocalEventQ = pSmObjCpuInfo->pCpuEventQ;    /* clear cpu notification info cache table */    bzero ((char *) smObjCpuInfoTbl,            sizeof (SM_OBJ_CPU_INFO) * SM_OBJ_MAX_CPU);    /* connect the shared memory objects interrupt handler */       if (smUtilIntConnect (HIGH_PRIORITY, (FUNCPTR) smObjNotifyHandler, 0, 			  pSmObjDesc->smDesc.intType,                           pSmObjDesc->smDesc.intArg1,                           pSmObjDesc->smDesc.intArg2, 			  pSmObjDesc->smDesc.intArg3) == ERROR)        {	return (ERROR);        }    /* calculate addr of cpu desc in global table */    pObjDesc = &((pSmObjDesc->cpuLocalAdrs) [smObjProcNum]);    pObjDesc->status = htonl (SM_CPU_ATTACHED); /* mark this cpu as attached */    pSmObjDesc->status = SM_CPU_ATTACHED;       /* also mark sh mem descr */    CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */    tmp = pObjDesc->status;                     /* BRIDGE FLUSH  [SPR 68334] */    return (OK);    }/******************************************************************************** smObjDetach - detach CPU from shared memory objects facility** This routine ends the "attachment" between the calling CPU and* the shared memory objects facility.  ** RETURNS: OK, or ERROR.** INTERNAL* Detaching a CPU that uses shared memory objects is not possible* as smObj are implemented now.  Indeed, if a CPU has a task pended* on a shared semaphore, there is a shared TCB attached to the semaphore** NOMANUAL*/STATUS smObjDetach    (    SM_DESC * pSmObjDesc       /* ptr to shared mem object descriptor */    )    {    if (pSmObjDesc == NULL)        {        return (ERROR);        }    /* PME for now no detachment from shared memory objects available */    return (ERROR);    }/******************************************************************************** smObjEventSend - send one or more events to remote CPU** This routine notifies one or more shared memory events to a remote CPU.* Notification informations are stored in the shared memory objects task* control block added to <pEventList> list.  The last parameter <destCpu>* contains the processor number to which events are sent.** Events are shared TCB of tasks to be added to the ready queue.** A spin-lock mechanism is used to prevent more than one processor to add * events to the same processor event queue at the same time.** In order to reduce bus traffic and interrupt number, the destination CPU * is interrupted only if its event queue was previously empty. ** This routine uses smMemIntGenFunc() to interrupt the destination CPU.** RETURNS: OK, or ERROR if cannot obtain access to CPU event queue.** ERRNO:*   S_smObjLib_LOCK_TIMEOUT** NOMANUAL*/STATUS smObjEventSend    (    SM_DL_LIST * pEventList,	/* list of events */    UINT32       destCpu    )    {    SM_OBJ_EVENT_Q *	pDestCpuEventQ;   /* remote CPU event queue */    BOOL		destEventQWasEmpty;	    int			level;    /*     * Cache eventQ and notification informations if this is     * the first time events are send to destCpu.     */    if (!smObjCpuInfoTbl [destCpu].cached)	{	smObjCpuInfoGet (&smObjDesc, destCpu, &smObjCpuInfoTbl [destCpu]);	smObjCpuInfoTbl[destCpu].cached = TRUE;        }    pDestCpuEventQ = smObjCpuInfoTbl [destCpu].pCpuEventQ;    /* ENTER LOCKED SECTION */    if (SM_OBJ_LOCK_TAKE (&pDestCpuEventQ->lock, &level) != OK)        {	smObjTimeoutLogMsg ("smObjEventSend", (char *) &pDestCpuEventQ->lock);        return (ERROR);                         /* can't take lock */        }    destEventQWasEmpty = SM_DL_EMPTY (&pDestCpuEventQ->eventList);    /* add shared TCBs to event queue */    smDllConcat (&pDestCpuEventQ->eventList, pEventList);    /* EXIT LOCKED SECTION */    SM_OBJ_LOCK_GIVE (&pDestCpuEventQ->lock, level);    /*      * now interrupt destination CPU only event queue was previously empty     */    if (destEventQWasEmpty)	{    	if (smUtilIntGen (&(smObjCpuInfoTbl[destCpu].smCpuDesc), destCpu) !=OK)    	    {	    return (ERROR);                    /* int gen routine error */    	    }	}	    return (OK);    }/******************************************************************************** smObjEventProcess - shared memory objects event processing** This routine is called at interrupt level to handle the remote CPU part* of a global semaphore give or flush.  It is called on the CPU that made the* semTake.** NOTE :* When the pending node is a remote node, the smObjTcb is removed from* the waiting list on the semGive or semFlush side and the TCB is put* on the ready queue on the semTake() side, otherwise since the notification* time is not null another semGive() or semFlush() could find the smObjTcb() in* the waiting list before the remote node have removed it.  During* the notification time the task is not in the shared semaphore* waiting list and not in the remote CPU ready queue.** NOMANUAL*/void smObjEventProcess    (    SM_DL_LIST * pEventList      /* list of event to process */    )    {    SM_OBJ_TCB * pSmObjTcb;    WIND_TCB   * pTcb;    int 	 level;    /*     * We are going to process each event stored in a local copy of      * the event list obtain by smObjNotifyHandler.     */    while (!(SM_DL_EMPTY (pEventList)))        {	/* 	 * We must lock out interrupts while removing shared TCBs from 	 * event list, because we can run here as deferred work and another	 * shared TCB event may be added to the global eventList 	 * we use to empty the CPU event queue in smObjNotifyHandler.	 */        	level = intLock ();        pSmObjTcb = (SM_OBJ_TCB *) smDllGet (pEventList);	intUnlock (level);	/* get the local TCB */	pTcb = (WIND_TCB *) ntohl ((int) pSmObjTcb->localTcb);	/* 	 * At this time the following can happen, a task delete, a timeout	 * or a signal can have change the status of the previously	 * pending task.  In that the incoming shared TCB must be dropped.	 * The fact that the task was deleted, timeout or signaled is	 * indicated by a NULL value in the localTcb pointer. 	 * See qFifoGRemove for more details.	 */	if (pTcb != NULL)	    {	    /* 	     * The task is still pending on the shared semaphore	     * we are giving.  Put it on the ready Queue.	     * When it comes here the shared TCB has its removedByGive	     * field set to TRUE.  We have to reset removedByGive	     * to indicate that this shared TCB can block again	     * on a shared semaphore otherwise a future call to	     * qFifoGRemove will get lost.	     */	    pSmObjTcb->removedByGive = htonl (FALSE);            /* don't disturb cache while in ISR, just trigger FIFO flush */            level = pSmObjTcb->removedByGive;   /* BRIDGE FLUSH  [SPR 68334] */            /* windview - level 2 event logging */	    EVT_TASK_1 (EVENT_OBJ_SEMGIVE, NULL);            windReadyQPut (pTcb);	    }	else	    {	    /* 	     * The task was deleted, was signaled or get a timeout,	     * we free the shared TCB.  The next call to semTake	     * on a shared semaphore for this task will allocate 	     * a new shared TCB since the pSmObjTcb field of the local	     * TCB has been set to NULL in qFifoGRemove.	     */	    smObjTcbFree (pSmObjTcb);	    }        }    }/******************************************************************************** smObjNotifyHandler - handle shared memory events** This routine processes all events currently stored in local CPU event queue. * Events are shared TCBs of tasks which were previously blocked* on a shared semaphore and which were unblock by another CPU doing* a semGive.** This routine must be connected to the shared memory interrupt, mailbox * or polling task. ** The CPU event queue is protected against concurrent access by a spin-lock.* To reduce interrupt lattency, access to the event queue is only* prevented while events are removed from it, not when they are processed.** When the shared memory backplane driver is used, this handler is connected to* the interrupt, mailbox, or polling task used by the backplane driver.** RETURNS: OK, or ERROR if cannot obtain access to CPU event queue.** ERRNO:*   S_smObjLib_LOCK_TIMEOUT** NOMANUAL*/LOCAL STATUS smObjNotifyHandler (void)    {    int                level;    /*      * What we have to do here is remove all the shared TCB from     * the CPU event queue and put them on a local eventList     * and process them.      * Note that there is no need of a while loop to check again for      * CPU event queue emptiness, since if a CPU adds events      * to it, it will generate an interrupt because we left     * the CPU event queue empty after smDllConcat.     */

⌨️ 快捷键说明

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