📄 smpktlib.c
字号:
** ERRNO: S_smPktLib_LOCK_TIMEOUT*/LOCAL STATUS smPktSllGet ( SM_SLL_LIST volatile * listLocalAdrs, /* local addr of packet list */ int baseAddr, /* addr conversion constant */ FUNCPTR tasRoutine, /* test-and-set routine addr */ FUNCPTR tasClearRoutine, /* test-and-set routine addr */ SM_SLL_NODE ** pNodeLocalAdrs /* location to put node addr */ ) { int oldLvl; /* saved interrupt level */ int count; /* temp value */ SM_SLL_NODE volatile * pNode; /* pointer to node */ /* Take list lock */ if (SM_LOCK_TAKE ((int *)&(listLocalAdrs->lock), tasRoutine, smPktTasTries, &oldLvl) != OK) { errno = S_smPktLib_LOCK_TIMEOUT; return (ERROR); /* can't take lock */ } /* Get first node from list, if any */ if ((pNode = (SM_SLL_NODE volatile *) ntohl (listLocalAdrs->head)) != NULL) { pNode = SM_OFFSET_TO_LOCAL ((int) pNode, baseAddr, SM_SLL_NODE *); /* convert to local address */ listLocalAdrs->head = pNode->next; /* next node (if any) is head */ count = ntohl (listLocalAdrs->count) - 1; if (count <= 0) /* if list now empty */ { listLocalAdrs->tail = htonl (0); /* clear tail pointer */ count = 0; } listLocalAdrs->count = htonl (count); } CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ count = listLocalAdrs->limit; /* BRIDGE FLUSH [SPR 68334] */ /* Release list lock */ SM_LOCK_GIVE ((int *)&(listLocalAdrs->lock), tasClearRoutine, oldLvl); /* Pass node address back to caller */ *pNodeLocalAdrs = (SM_SLL_NODE *) pNode; /* local node addr, or NULL */ return (OK); }/******************************************************************************** smPktSllPut - add a shared memory node to a singly-linked list** This routine attempts to add a shared memory node to the specified* singly-linked list. The node to be added is identified by <nodeLocalAdrs>.* Unless the list has reached its maximum number of entries, the node* will be added at the tail of the list. The bus address of the node is* used in the list entry.** This routine uses the specified test-and-set function, <tasRoutine>, to* obtain exclusive access to the linked list lock. If the lock cannot* be acquired within the number of tries specified by the smPktTasTries* global variable, this routine will return ERROR.** If the list already contains its maximum number of node entries, this* routine will return ERROR.** If <pListWasEmpty> is non-null and the node is successfully added* to the list, this routine will set the BOOL pointed to by* <pListWasEmpty> to TRUE if there were no previous nodes in the list.** RETURNS: OK, or ERROR if packet ptr is NULL, list full, or could* not acquire list lock.** ERRNO: S_smPktLib_LOCK_TIMEOUT, S_smPktLib_LIST_FULL*/LOCAL STATUS smPktSllPut ( SM_SLL_LIST volatile * listLocalAdrs, /* local addr of packet list */ int base, /* base address */ FUNCPTR tasRoutine, /* test-and-set routine addr */ FUNCPTR tasClearRoutine, /* test-and-set routine addr */ SM_SLL_NODE volatile * nodeLocalAdrs, /* local addr of node */ BOOL * pListWasEmpty /* set to true if adding to * empty list */ ) { int oldLvl; /* saved interrupt level */ int nodeOff; /* pointer to node */ SM_SLL_NODE volatile * tailLocalAdrs; /* pointer to list tail node */ nodeLocalAdrs->next = 0; /* mark node as end of list */ nodeOff = htonl (SM_LOCAL_TO_OFFSET (nodeLocalAdrs, base)); /* Take list lock */ if (SM_LOCK_TAKE ((int *)&(listLocalAdrs->lock), tasRoutine, smPktTasTries, &oldLvl) != OK) { errno = S_smPktLib_LOCK_TIMEOUT; return (ERROR); /* can't take lock */ } /* Add node to list */ if (ntohl (listLocalAdrs->count) >= ntohl (listLocalAdrs->limit)) { SM_LOCK_GIVE ((int *)&(listLocalAdrs->lock), tasClearRoutine, oldLvl); errno = S_smPktLib_LIST_FULL; return (ERROR); /* list has max nodes already */ } /* if list previously empty */ if (ntohl (listLocalAdrs->tail) == 0) { if (pListWasEmpty != NULL) *pListWasEmpty = TRUE; /* node is new head also */ listLocalAdrs->head = nodeOff; } else { if (pListWasEmpty != NULL) *pListWasEmpty = FALSE; tailLocalAdrs = SM_OFFSET_TO_LOCAL (ntohl (listLocalAdrs->tail), base, SM_SLL_NODE volatile *); /* get addr of tail node */ tailLocalAdrs->next = nodeOff; /* link new node to old tail */ } listLocalAdrs->tail = nodeOff; /* node is new tail */ listLocalAdrs->count = ntohl (htonl (listLocalAdrs->count) + 1); /* one more node in list */ CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ nodeOff = listLocalAdrs->limit; /* BRIDGE FLUSH [SPR 68334] */ /* Release list lock */ SM_LOCK_GIVE ((int *)&(listLocalAdrs->lock), tasClearRoutine, oldLvl); return (OK); }/******************************************************************************** smPktDetach - detach CPU from shared memory** This routine ends the "attachment" between the calling CPU and* the shared memory area specified by <pSmPktDesc>. No further shared* memory operations may be performed until a subsequent smPktAttach()* is completed.** RETURNS: OK, or ERROR.** ERRNO: S_smPktLib_NOT_ATTACHED*/STATUS smPktDetach ( SM_PKT_DESC * pSmPktDesc, /* ptr to shared mem descriptor */ BOOL noFlush /* true if input queue should not * be flushed */ ) { SM_PKT_CPU_DESC volatile * pPktCpuDesc; /* cpu descriptor */ SM_PKT volatile * pPkt; /* pointer to input packet */ SM_DESC * pSmDesc = (SM_DESC *) &pSmPktDesc->smDesc; int tmp; /* temp storage */ /* Check that this cpu is connected to shared memory */ if (pSmPktDesc->status != SM_CPU_ATTACHED) { errno = S_smPktLib_NOT_ATTACHED; return (ERROR); /* local cpu is not attached */ } if (smDetach (pSmDesc) == ERROR) return (ERROR); /* get addr of cpu descriptor */ pPktCpuDesc = (SM_PKT_CPU_DESC volatile *) &((pSmPktDesc->cpuLocalAdrs) \ [pSmDesc->cpuNum]); pPktCpuDesc->status = htonl (SM_CPU_NOT_ATTACHED);/* mark as not attached */ pSmPktDesc->status = SM_CPU_NOT_ATTACHED; /* also mark sh mem descr */ CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = pPktCpuDesc->status; /* BRIDGE FLUSH [SPR 68334] */ if (noFlush == FALSE) /* flush input queue */ { FOREVER { if (smPktSllGet (&(pPktCpuDesc->inputList), pSmDesc->base, pSmDesc->tasRoutine, pSmDesc->tasClearRoutine, (SM_SLL_NODE **) &pPkt) != OK) return (ERROR); /* error getting input packet */ if (pPkt == NULL) break; /* no more input packets */ if (smPktSllPut (&(pSmPktDesc->hdrLocalAdrs->freeList), pSmDesc->base, pSmDesc->tasRoutine, pSmDesc->tasClearRoutine, &(pPkt->header.node), NULL) != OK) return (ERROR); /* error adding to free list */ } } return (OK); }/******************************************************************************** smPktInfoGet - get current status information about shared memory** This routine obtains various pieces of information which describe the* current state of the shared memory area specified by <pSmPktDesc>. The* current information is returned in a special data structure, SM_PKT_INFO,* whose address is specified by <pInfo>. The structure must have been* allocated before this routine is called.** RETURNS: OK, or ERROR if this CPU is not attached to shared memory area.** ERRNO: S_smPktLib_NOT_ATTACHED*/STATUS smPktInfoGet ( SM_PKT_DESC * pSmPktDesc, /* shared memory descriptor */ SM_PKT_INFO * pInfo /* info structure to fill */ ) { SM_PKT_MEM_HDR volatile * pHdr; /* shared memory header */ SM_PKT_CPU_DESC volatile * pCpuDesc; /* cpu descriptor */ int ix; /* index variable */ int tmp; /* temp storage */ /* Check that this cpu is connected to shared memory */ if (pSmPktDesc->status != SM_CPU_ATTACHED) { errno = S_smPktLib_NOT_ATTACHED; return (ERROR); /* local cpu is not attached */ } if (smInfoGet (&(pSmPktDesc->smDesc), &(pInfo->smInfo)) == ERROR) return (ERROR); /* Use local address to get info from shared memory packet header */ pHdr = (SM_PKT_MEM_HDR volatile *) pSmPktDesc->hdrLocalAdrs; CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = pHdr->maxPktBytes; /* PCI bridge bug [SPR 68844]*/ pInfo->maxPktBytes = ntohl (pHdr->maxPktBytes);/* max data bytes per pkt */ pInfo->totalPkts = ntohl (pHdr->freeList.limit);/* total number */ pInfo->freePkts = ntohl (pHdr->freeList.count);/* number free */ /* Get count of attached cpu's starting with first cpu table entry */ pCpuDesc = (SM_PKT_CPU_DESC volatile *) pSmPktDesc->cpuLocalAdrs; pInfo->attachedCpus = 0; for (ix = 0; ix < pInfo->smInfo.maxCpus; ix++) { if (ntohl (pCpuDesc->status) == SM_CPU_ATTACHED) pInfo->attachedCpus++; pCpuDesc++; /* next entry */ } return (OK); }/******************************************************************************** smPktCpuInfoGet - 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_PKT_CPU_INFO, whose address is specified by <pCpuInfo>. (The* structure must have been allocated before this routine is called.)** RETURNS: OK, or ERROR.** ERRNO: S_smPktLib_NOT_ATTACHED*/STATUS smPktCpuInfoGet ( SM_PKT_DESC * pSmPktDesc, /* pkt descriptor */ int cpuNum, /* cpu to get info about */ SM_PKT_CPU_INFO * pCpuInfo /* structure to fill */ ) { SM_PKT_CPU_DESC volatile * pCpuDesc; /* ptr to cpu descriptor */ int tmp; /* temp storage */ /* Check that the local cpu is connected to shared memory */ if (pSmPktDesc->status != SM_CPU_ATTACHED) { errno = S_smPktLib_NOT_ATTACHED; return (ERROR); /* local cpu is not attached */ } if (cpuNum == NONE) cpuNum = pSmPktDesc->smDesc.cpuNum; if (smCpuInfoGet (&(pSmPktDesc->smDesc), cpuNum, &(pCpuInfo->smCpuInfo)) == ERROR) return (ERROR); /* get address of cpu descr */ pCpuDesc = (SM_PKT_CPU_DESC volatile *)&(pSmPktDesc->cpuLocalAdrs[cpuNum]); CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = pCpuDesc->status; /* PCI bridge bug [SPR 68844]*/ pCpuInfo->status = ntohl (pCpuDesc->status);/* attached or not attached */ /* Get packet counts */ pCpuInfo->inputPkts = ntohl (pCpuDesc->inputList.count); /* current pkts in input queue*/ pCpuInfo->maxInputPkts = ntohl (pCpuDesc->inputList.limit); /* max pkts allowed in queue */ /* * XXX - free list counts - for future use when cpu's have free lists... * * pCpuInfo->freePkts = ntohl (pCpuDesc->freeList.count); * pCpuInfo->totalPkts = ntohl (pCpuDesc->freeList.limit); * */ pCpuInfo->freePkts = 0; /* (future use) */ return (OK); }/******************************************************************************** smPktBeat - increment packet heartbeat in shared memory anchor** This routine increments the shared memory packet "heartbeat". The heartbeat* is used by processors using the shared memory packet library to* confirm that the shared memory network is active. The shared memory* area whose heartbeat is to be incremented is specifed by <pSmPktHdr>, which* is the address of a shared memory packet header region in which the heartbeat* count is maintained.** This routine should be called periodically by the master CPU.** RETURNS: N/A*/void smPktBeat ( SM_PKT_MEM_HDR * pSmPktHdr /* ptr to sm packet header */ ) { SM_PKT_MEM_HDR volatile * pPktHdrv = (SM_PKT_MEM_HDR volatile *) pSmPktHdr; int tmp; /* temp storage */ /* Increment heartbeat */ tmp = pPktHdrv->heartBeat; /* PCI bridge bug [SPR 68844]*/ pPktHdrv->heartBeat = htonl (ntohl (pPktHdrv->heartBeat) + 1); CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = pPktHdrv->heartBeat; /* BRIDGE FLUSH [SPR 68334] */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -