📄 ixosbuflib.c
字号:
return (OK); }/********************************************************************************* ixMBlkFree - free the given mBlk** This function frees the given mBlk and returns it to the mBlk pool.** RETURNS: N/A** NOMANUAL*/LOCAL void ixMBlkFree ( NET_POOL_ID pNetPool, /* pointer to the net pool */ M_BLK_ID pMblk /* mBlk to free */ ) { FAST int ms; pMblk->mBlkHdr.mNextPkt = NULL; ms = intLock (); pNetPool->pPoolStat->mTypes [pMblk->mBlkHdr.mType]--; pNetPool->pPoolStat->mTypes [MT_FREE]++; pMblk->mBlkHdr.mType = MT_FREE; pMblk->mBlkHdr.mNext = pNetPool->pmBlkHead; pNetPool->pmBlkHead = pMblk; /* add the mbuf to the free list */ intUnlock (ms); }/********************************************************************************* ixClBlkFree - free the given cluster Blk** This function frees the given clBlk and returns it to the cluster Blk pool.** RETURNS: N/A** NOMANUAL*/LOCAL void ixClBlkFree ( CL_BLK_ID pClBlk /* clBlk to free */ ) { FAST int level; CL_POOL_ID pClPool; CL_BUF_ID pClBuf; NET_POOL_ID pNetPool; /* pointer to the net pool */ pNetPool = pClBlk->pNetPool; pClBuf = (CL_BUF_ID)pClBlk->clNode.pClBuf; level = intLock (); /* lock interrupts briefly */ if (pClBuf == NULL) /* no cluster attached */ goto returnClBlk; else if (--(pClBlk->clRefCnt) == 0) { if (pClBlk->pClFreeRtn != NULL) { /* call the free routine if associated with one */ intUnlock (level); (*pClBlk->pClFreeRtn) (pClBlk->clFreeArg1, pClBlk->clFreeArg2, pClBlk->clFreeArg3); level = intLock (); } else { /* return the cluster to its pool */ pClPool = pNetPool->clTbl[0]; pClBuf->pClNext = pClPool->pClHead; pClPool->pClHead = pClBuf; /* update mask */ pClPool->clNumFree++; } goto returnClBlk; } else goto clBlkFreeEnd; returnClBlk: /* free the cluster blk and add it to the free list */ pClBlk->clNode.pClBlkNext = pNetPool->pClBlkHead; pNetPool->pClBlkHead = pClBlk; clBlkFreeEnd: intUnlock (level); }/********************************************************************************* ixClusterFree - free a cluster of a given size.** This function frees a cluster of given size in a net pool** RETURNS: N/A** NOMANUAL*/LOCAL void ixClusterFree ( NET_POOL_ID pNetPool, /* pointer to the net pool */ char * pClBuf /* pointer to the cluster buffer */ ) { CL_POOL_ID pClPool; FAST int level; pClPool = pNetPool->clTbl[0]; level = intLock (); if (pClPool->clNumFree == 0) ((CL_BUF_ID)pClBuf)->pClNext = NULL; else ((CL_BUF_ID)pClBuf)->pClNext = pClPool->pClHead; pClPool->pClHead = (CL_BUF_ID)pClBuf; /* update mask */ pClPool->clNumFree++; intUnlock (level); }/********************************************************************************* ixMBlkClFree - free an mBlk/cluster pair.** This function frees a mBlk/cluster pair. This function returns a pointer* to the next mBlk which is connected to the current one. This routine will* free the cluster only if it is attached to the mBlk.** RETURNS: M_BLK_ID or NULL.** NOMANUAL*/LOCAL M_BLK_ID ixMBlkClFree ( NET_POOL_ID pNetPool, /* pointer to net pool */ M_BLK_ID pMblk /* pointer to the mBlk */ ) { M_BLK_ID pMblkNext; /* pointer to the next mBlk */ if (pMblk->mBlkHdr.mType == MT_FREE) {#ifdef NETBUF_DEBUG logMsg ("mBlkClFree -- Invalid mBlk\n", 0, 0, 0, 0, 0, 0);#endif /* NETBUF_DEBUG */ errno = S_netBufLib_MBLK_INVALID; return (NULL); } pMblkNext = pMblk->mBlkHdr.mNext; /* free the cluster first if it is attached to the mBlk */ if (M_HASCL(pMblk)) netClBlkFree (pMblk->pClBlk->pNetPool, pMblk->pClBlk); ixMBlkFree (pNetPool, pMblk); /* free the mBlk */ return (pMblkNext); }/********************************************************************************* ixMBlkGet - get a free mBlk** This routine returns a free mBlk if one is available. If the <canWait>* parameter is set to M_WAIT and an mBlk is not immediately available, the* routine repeats the allocation attempt after calling any installed garbage* collection routine.** RETURNS: M_BLK_ID or NULL if none available** NOMANUAL*/LOCAL M_BLK_ID ixMBlkGet ( NET_POOL_ID pNetPool, /* pointer to the net pool */ int canWait, /* M_WAIT/M_DONTWAIT */ UCHAR type /* mBlk type */ ) { M_BLK_ID pMblk = NULL; /* pointer to mbuf */ int level; /* level of interrupt */ reTry: level = intLock(); /* lock interrupts very briefly */ if ((pMblk = pNetPool->pmBlkHead) != NULL) { pNetPool->pmBlkHead = pMblk->mBlkHdr.mNext; pNetPool->pPoolStat->mTypes [MT_FREE]--; pNetPool->pPoolStat->mTypes [type]++; intUnlock (level); /* unlock interrupts */ if (pMblk->mBlkHdr.mType != MT_FREE) {#ifdef NETBUF_DEBUG logMsg("mBlkGet free error:\n", 0, 0, 0, 0, 0, 0);#endif /* NETBUF_DEBUG */ errno = S_netBufLib_MBLK_INVALID; return (NULL); } pMblk->mBlkHdr.mType = type; pMblk->mBlkHdr.mNext = NULL; pMblk->mBlkHdr.mNextPkt = NULL; pMblk->mBlkHdr.mFlags = 0; } else /* if (canWait != M_ISR) */ { if (canWait == M_WAIT) { if (_pNetBufCollect) { intUnlock (level); /* unlock interrupts */ (*_pNetBufCollect) (pNetPool->pPoolStat); canWait = M_DONTWAIT; goto reTry; } } pNetPool->pPoolStat->mDrops++; intUnlock (level); errnoSet (S_netBufLib_NO_POOL_MEMORY); } return (pMblk); }/********************************************************************************* ixClBlkGet - get a free clBlk** This routine returns a free clBlk if one is available. If the <canWait>* parameter is set to M_WAIT and a clBlk is not immediately available, the* routine repeats the allocation attempt after calling any installed garbage* collection routine.** RETURNS: CL_BLK_ID or NULL.** NOMANUAL*/LOCAL CL_BLK_ID ixClBlkGet ( NET_POOL_ID pNetPool, /* pointer to the net pool */ int canWait /* M_WAIT/M_DONTWAIT */ ) { CL_BLK_ID pClBlk = NULL; /* pointer to mbuf */ int level; /* level of interrupt */ reTry: level = intLock(); /* lock interrupts very briefly */ if ((pClBlk = pNetPool->pClBlkHead) != NULL) { pNetPool->pClBlkHead = pClBlk->clNode.pClBlkNext; intUnlock (level); /* unlock interrupts */ pClBlk->clNode.pClBuf = NULL; pClBlk->pClFreeRtn = NULL; pClBlk->clRefCnt = 0; pClBlk->pNetPool = pNetPool; /* netPool originator */ } else /* if (canWait != M_ISR) */ { if (canWait == M_WAIT) { if (_pNetBufCollect) { intUnlock (level); /* unlock interrupts */ (*_pNetBufCollect) (pNetPool->pPoolStat); canWait = M_DONTWAIT; goto reTry; } } intUnlock (level); errnoSet (S_netBufLib_NO_POOL_MEMORY); } return (pClBlk); }/********************************************************************************* ixClusterGet - get a new cluster of a given cluster pool.** This function returns a cluster given a pool pointer. The reference count* for the cluster is incremented.** RETURNS: pointer to a cluster or NULL** NOMANUAL*/LOCAL char * ixClusterGet ( NET_POOL_ID pNetPool, /* pointer to the net pool */ CL_POOL_ID pClPool /* ptr to the cluster pool */ ) { int level; /* level of interrupt */ CL_BUF_ID pClBuf; /* ptr to the cluster buffer */ level = intLock (); /* lock interrupts briefly */ if (pClPool->pClHead == NULL) /* return if no buffers */ { if (pClPool->clNumFree > 0) logMsg("ixClusterGet: pClPool->pClHead %p pClPool->clNumFree %d\n", (int)pClPool->pClHead,pClPool->clNumFree,0,0,0,0); intUnlock (level); return (NULL); } pClBuf = pClPool->pClHead; /* update the head */ pClPool->clNumFree--; /* decrement the free count */ if (pClPool->clNumFree == 0) pClPool->pClHead = NULL; else pClPool->pClHead = pClBuf->pClNext; pClPool->clUsage++; /* increment the usage count */ intUnlock (level); return ((char *)pClBuf); }/********************************************************************************* endMClGet - get a new mBlk/cluster pair.** This function gets a free cluster from the NET_POOL and joins it with* the mBlk passed to it. An mBlk must be pre allocated and passed to this* function.** RETURNS: OK or ERROR.** NOMANUAL*/LOCAL STATUS ixMClGet ( NET_POOL_ID pNetPool, /* pointer to the net pool */ M_BLK_ID pMblk, /* mBlk to embed the cluster in */ int bufSize, /* size of the buffer to get */ int canWait, /* wait or dontwait */ BOOL bestFit /* TRUE/FALSE */ ) { CL_POOL_ID pClPool; /* pointer to the cluster pool */ CL_BUF_ID pClBuf = NULL; /* pointer to the cluster buffer */ CL_BLK_ID pClBlk = NULL; /* pointer to the cluster blk */ FAST int ms; /* integer for level */ /* check pMblk */ if ((pMblk == NULL) || ((pClBlk = ixClBlkGet (pNetPool, canWait)) == NULL)) goto mClGetError; /* get the pool pointer */ if ((pClPool = pNetPool->clTbl [0]) == NULL) {#ifdef NETBUF_DEBUG logMsg ("endMClGet: Invalid cluster type\n", 0, 0, 0, 0, 0, 0);#endif /* NETBUF_DEBUG */ errno = S_netBufLib_CLSIZE_INVALID; goto mClGetError; } reTry: ms = intLock(); /* lock interrupts briefly */ if (pClPool->pClHead == NULL) { if (canWait == M_WAIT) /* want for buffers */ { if (_pNetBufCollect) { intUnlock (ms); (*_pNetBufCollect) (pNetPool->pPoolStat); canWait = M_DONTWAIT; goto reTry; } } } if ((pClBuf = pClPool->pClHead)) { pClPool->pClHead = pClBuf->pClNext; pClPool->clNumFree--; pClPool->clUsage++; intUnlock (ms); } else { pNetPool->pPoolStat->mDrops++; /* no. times failed to find space */ intUnlock (ms); errnoSet (S_netBufLib_NO_POOL_MEMORY); goto mClGetError; } pMblk->mBlkHdr.mData = (caddr_t) pClBuf; pMblk->mBlkHdr.mFlags |= M_EXT; pClBlk->clNode.pClBuf = (caddr_t) pClBuf; pClBlk->clSize = pClPool->clSize; /* pClBlk->pClFreeRtn = ixClBlkFree; pClBlk->clFreeArg1 = pClBlk; pClBlk->clFreeArg2 = 0; pClBlk->clFreeArg3 = 0; */ pClBlk->clRefCnt = 1; pMblk->pClBlk = pClBlk; return (OK); /* return OK */ mClGetError: if (pClBlk != NULL) ixClBlkFree (pClBlk); return (ERROR); /* return ERROR */ }/********************************************************************************* endClPoolIdGet - return a pool Id for a given cluster Size** This function returns a poolID for a given cluster Size.* If this returns NULL then the corresponding pool has not been initialized.** RETURNS: CL_POOL_ID or NULL.** NOMANUAL*/LOCAL CL_POOL_ID ixClPoolIdGet ( NET_POOL_ID pNetPool, /* pointer to the net pool */ int bufSize, /* size of the buffer */ BOOL bestFit /* TRUE/FALSE */ ) { return (pNetPool->clTbl [0]); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -