📄 smobjlib.c
字号:
/* * We must check for event queue emptiness because * we are connected to the same interrupt as the backplane driver. */ if (!(SM_DL_EMPTY (&pLocalEventQ->eventList))) { /* ENTER LOCKED SECTION */ if (SM_OBJ_LOCK_TAKE (&pLocalEventQ->lock, &level) != OK) { smObjTimeoutLogMsg ("smObjNotifyHandler", (char *) &pLocalEventQ->lock); return (ERROR); /* can't take lock */ } /* * Now, in order to minimize interrupt lattency, we remove all * the events from event queue at the same time and put them in * a local event list. */ smDllConcat (&eventList, &pLocalEventQ->eventList); /* EXIT LOCKED SECTION */ SM_OBJ_LOCK_GIVE (&pLocalEventQ->lock, level); /* * Now process list of events out of the locked section, * if we are already in kernel state, defer the work. */ /* * We can come here with an empty list in the case where * shared memory objects and sm backplane driver are used * at the same time and the interrupt was for an sm packet * not for a smObj event. In that case smObjEventProcess * will essentially be a no-op. */ if (kernelState) { workQAdd1 ((FUNCPTR) smObjEventProcess, (int) &eventList); } else { kernelState = TRUE; /* ENTER KERNEL */ smObjEventProcess (&eventList); /* unblock tasks */ windExit (); /* EXIT KERNEL */ } /* * If we were notified by a bus interrupt we must acknowledge it. * This is not done here since it is not possible to acknowledge a bus * interrupt more than once on most i960 boards. Under heavy load * on both the backplane driver and shared memory objects the backplane * driver will also acknowledge the interrupt and cause the CPU to * reboot. The only solution is to handle the acknowledge in the * smUtilIntRoutine() but this is only possible with a rework of both * VxMP and the shared memory network code. */ } return (OK); }/******************************************************************************** smObjLocalToGlobal - convert a local address to a global address (VxMP Option)** This routine converts a local shared memory address <localAdrs> to its* corresponding global value. This routine does not verify that* <localAdrs> is really a valid local shared memory address.** All addresses stored in shared memory are global. Any access made to shared* memory by the local CPU must be done using local addresses. This routine* and smObjGlobalToLocal() are used to convert between these address types.** AVAILABILITY* This routine is distributed as a component of the unbundled shared memory* objects support option, VxMP.* * RETURNS: The global shared memory address pointed to by <localAdrs>.** SEE ALSO: smObjGlobalToLocal()*/void * smObjLocalToGlobal ( void * localAdrs /* local address to convert */ ) { /* test memory bounds PME */ return ((void *) LOC_TO_GLOB_ADRS (localAdrs)); }/******************************************************************************** smObjGlobalToLocal - convert a global address to a local address (VxMP Option)** This routine converts a global shared memory address <globalAdrs> to its* corresponding local value. This routine does not verify that <globalAdrs>* is really a valid global shared memory address.** All addresses stored in shared memory are global. Any access made to shared* memory by the local CPU must be done using local addresses. This routine* and smObjLocalToGlobal() are used to convert between these address types.** AVAILABILITY* This routine is distributed as a component of the unbundled shared memory* objects support option, VxMP.* * RETURNS: The local shared memory address pointed to by <globalAdrs>.** SEE ALSO: smObjLocalToGlobal()*/void * smObjGlobalToLocal ( void * globalAdrs /* global address to convert */ ) { /* * PME test memory bounds not in the range * SM_OBJ_FREE_ADRS - (SM_OBJ_FREE_ADRS + SM_OBJ_FREE_SIZE) */ return ((void *) GLOB_TO_LOC_ADRS (globalAdrs)); }/******************************************************************************** smObjTcbInit - initialize shared Task Control Block** This routine allocates a shared task control block from the shared memory * TCB dedicated pool (smTcbPartId) and initializes it. The shared TCB pointer* is stored in the pSmObjTcb field of the task control block.** This function is called the first time a task block on a shared semaphore* (ie in semTake).** The shared Task Control Block is de-allocated and the associated* memory is given back to the shared TCB dedicated pool when the task* exits or is deleted.** RETURNS: OK, or ERROR if cannot allocate shared TCB.* * ERRNO:* S_smMemLib_NOT_INITIALIZED* S_smMemLib_NOT_ENOUGH_MEMORY* S_smObjLib_LOCK_TIMEOUT** NOMANUAL*/STATUS smObjTcbInit (void) { WIND_TCB * pTcb; pTcb = (WIND_TCB *) taskIdCurrent; /* get current tcb */ /* allocate shared TCB from shared TCBs partition */ pTcb->pSmObjTcb = (SM_OBJ_TCB *) smFixBlkPartAlloc (smTcbPartId); if (pTcb->pSmObjTcb == NULL) { return (ERROR); } /* initialize shared TCB */ bzero ((char *) pTcb->pSmObjTcb, sizeof (SM_OBJ_TCB)); pTcb->pSmObjTcb->ownerCpu = htonl (smObjProcNum); /* our proc number */ /* local TCB we belong to */ pTcb->pSmObjTcb->localTcb = (WIND_TCB *) htonl ((int) pTcb); CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ return (OK); }/******************************************************************************** smObjTcbFree - free shared Task Control Block** This routine gives back a shared task control block to the shared memory* TCB dedicated pool (smTcbPartId).** The shared Task Control Block is de-allocated and the associated* memory is given back to the shared TCB dedicated pool when the task* exits or is deleted.** RETURNS: OK, or ERROR if cannot free shared TCB.** ERRNO:* S_smMemLib_NOT_INITIALIZED* S_smObjLib_LOCK_TIMEOUT** NOMANUAL*/STATUS smObjTcbFree ( SM_OBJ_TCB * pSmObjTcb /* pointer to shared TCB to be freed */ ) { return (smFixBlkPartFree (smTcbPartId, (char *) pSmObjTcb)); }/******************************************************************************** smObjCpuInfoGet - get information about a single CPU using shared memory** This routine obtains a variety of information describing the CPU specified* by <cpuNum>. If <cpuNum> is NONE (-1), this routine returns information* about the local (calling) CPU. The information is returned in a special* structure, SM_CPU_INFO, whose address is specified by <pCpuInfo>. (The* structure must have been allocated before this routine is called.)** RETURNS: OK, or ERROR.** NOMANUAL*/LOCAL STATUS smObjCpuInfoGet ( SM_OBJ_DESC * pSmObjDesc, /* ptr to shared memory descriptor */ int cpuNum, /* number of cpu to get info about */ SM_OBJ_CPU_INFO * pSmObjCpuInfo /* cpu info structure to fill */ ) { SM_CPU_DESC volatile * pCpuDesc; /* ptr to cpu descriptor */ int tmp; /* temp storage */ /* Report on local cpu if NONE specified */ if (cpuNum == NONE) { cpuNum = pSmObjDesc->smDesc.cpuNum; } /* Get info from cpu descriptor */ if (cpuNum < 0 || cpuNum >= pSmObjDesc->smDesc.maxCpus) { errno = S_smLib_INVALID_CPU_NUMBER; return (ERROR); /* cpu number out of range */ } /* get address of cpu descr */ pCpuDesc = (SM_CPU_DESC volatile *) &(pSmObjDesc->smDesc.cpuTblLocalAdrs \ [cpuNum]); CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = pCpuDesc->status; /* PCI bridge bug [SPR 68844]*/ pSmObjCpuInfo->smCpuDesc.status = pCpuDesc->status; /* attached or not attached */ pSmObjCpuInfo->smCpuDesc.intType = pCpuDesc->intType; /* interrupt type */ pSmObjCpuInfo->smCpuDesc.intArg1 = pCpuDesc->intArg1; /* interrupt argument #1 */ pSmObjCpuInfo->smCpuDesc.intArg2 = pCpuDesc->intArg2; /* interrupt argument #2 */ pSmObjCpuInfo->smCpuDesc.intArg3 = pCpuDesc->intArg3; /* interrupt argument #3 */ /* get event Q pointer */ pSmObjCpuInfo->pCpuEventQ = &(pSmObjDesc->cpuLocalAdrs[cpuNum].smObjEventQ); return (OK); }/******************************************************************************** smObjTimeoutLogMsg - notify spin-lock take timeout** This routine prints a message on the standard output when an attempt* to get lock access on a shared ressource failed if the global* boolean smObjTimeoutLog is set to TRUE, otherwise only the error* status is set to S_smObjLib_LOCK_TIMEOUT.** <routineName> is a string containing the name of the function where* attempt to take lock has failed.** <lockLocalAdrs> is the local address of the shared memory spin-lock.** NOMANUAL*/void smObjTimeoutLogMsg ( char * routineName, char * lockLocalAdrs ) { if (smObjTimeoutLog) { logMsg ("ERROR : %s cannot take lock at address %#x.\n", (int) routineName, (int) lockLocalAdrs, 0, 0, 0, 0); } errno = S_smObjLib_LOCK_TIMEOUT; }/******************************************************************************** smObjTimeoutLogEnable - control logging of failed attempts to take a spin-lock (VxMP Option)** This routine enables or disables the printing of a message when* an attempt to take a shared memory spin-lock fails.** By default, message logging is enabled.** AVAILABILITY* This routine is distributed as a component of the unbundled shared memory* objects support option, VxMP.* * RETURNS: N/A*/void smObjTimeoutLogEnable ( BOOL timeoutLogEnable /* TRUE to enable, FALSE to disable */ ) { smObjTimeoutLog = timeoutLogEnable; }/******************************************************************************** smObjBeat - increment shared memory objects hearbeat** This routine continuously restart itself to increment the shared * memory objects heartbeat.** RETURNS: N/A** NOMANUAL*/LOCAL void smObjBeat ( UINT * pHeartBeat ) { int tmp; /* temp storage */ CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = *pHeartBeat; /* PCI bridge bug [SPR 68844]*/ *pHeartBeat = htonl (ntohl (*pHeartBeat) + 1); /* increment heartbeat */ CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = *pHeartBeat; /* BRIDGE FLUSH [SPR 68334] */ /* start a watchdog to call ourself every smObjHeartBeatRate */ wdStart (smObjWdog, smObjHeartBeatRate, (FUNCPTR) smObjBeat, (int) pHeartBeat); }/******************************************************************************** smObjTcbFreeLogMsg - notify shared TCB free failure** This routine prints a message on the standard output when * a shared TCB have not been given back to the shared TCB partition * because taskDestroy was unable to take the shared TCB partition spin-lock.** NOMANUAL*/void smObjTcbFreeLogMsg (void) { static int failNum; failNum++; if (smObjTimeoutLog) { logMsg ("WARNING: shared TCB not freed.\n", 0, 0, 0, 0, 0, 0); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -