📄 endnetbuflib.c
字号:
int num, /* number of units to allocate */ int unitSize, /* size of each unit */ int headerSize, /* hidden header size */ char * memArea /* pre allocated memory area */ ) { if (((int) unitSize & ~(sizeof (void *) - 1)) != unitSize ) { errno = S_netBufLib_MEMSIZE_UNALIGNED; return (ERROR); /* unaligned size */ } unitSize += headerSize; /* adjust for NET_POOL_ID */ if (memArea == NULL) { errno = S_netBufLib_MEMAREA_INVALID; return (ERROR); } if (((int) memArea & ~(sizeof (void *) - 1)) != (int)memArea ) { errno = S_netBufLib_MEM_UNALIGNED; return (ERROR); /* unaligned memory */ } bzero ((char *)memArea, (num * unitSize)); return (OK); }/********************************************************************************* _endMBlkFree - free the given mBlk** This function frees the given mBlk and returns it to the mBlk pool.** RETURNS: N/A** NOMANUAL*/LOCAL void _endMBlkFree ( 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); }/********************************************************************************* _endClBlkFree - 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 _endClBlkFree ( CL_BLK_ID pClBlk /* clBlk to free */ ) { FAST int level; 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 { _endClFree (pNetPool, (char *)pClBuf); } 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); }/********************************************************************************* _endClFree - 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 _endClFree ( NET_POOL_ID pNetPool, /* pointer to the net pool */ char * pClBuf /* pointer to the cluster buffer */ ) { FAST int level; END_CL_POOL * pEndClPool; pEndClPool = (END_CL_POOL *)pNetPool->clTbl[0]; level = intLock (); if (pEndClPool->clPool.clNumFree < pEndClPool->clPool.clNum) { pEndClPool->clPool.clNumFree++; pEndClPool->clFreeArray[pEndClPool->clPool.clNumFree] = (UINT32)pClBuf; } intUnlock (level); }/********************************************************************************* _endMBlkClFree - 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 _endMBlkClFree ( 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); _endMBlkFree (pNetPool, pMblk); /* free the mBlk */ return (pMblkNext); }/********************************************************************************* _endMBlkGet - 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 _endMBlkGet ( 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); }/********************************************************************************* _endClBlkGet - 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 _endClBlkGet ( 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); }/********************************************************************************* _endClusterGet - 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 * _endClusterGet ( 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 */ END_CL_POOL * pEndClPool; pEndClPool = (END_CL_POOL *)pClPool; level = intLock (); /* lock interrupts briefly */ if (pClPool->clNumFree > 0) { pClBuf = (CL_BUF_ID)pEndClPool->clFreeArray[pClPool->clNumFree]; pClPool->clNumFree--; } else { intUnlock (level); return (NULL); } 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 _endMClGet ( 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_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 */ END_CL_POOL * pEndClPool; /* check pMblk */ if ((pMblk == NULL) || ((pClBlk = _endClBlkGet (pNetPool, canWait)) == NULL)) goto mClGetError; /* get the pool pointer */ if ((pEndClPool = (END_CL_POOL *)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 (pEndClPool->clPool.clNumFree == 0) { if (canWait == M_WAIT) /* want for buffers */ { if (_pNetBufCollect) { intUnlock (ms); (*_pNetBufCollect) (pNetPool->pPoolStat); canWait = M_DONTWAIT; goto reTry; } } } if ((pClBuf =(CL_BUF_ID) _endClusterGet(pNetPool, (CL_POOL_ID)pEndClPool)) != NULL) 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 = pEndClPool->clPool.clSize; pClBlk->pClFreeRtn = NULL; pClBlk->clRefCnt = 1; pMblk->pClBlk = pClBlk; return (OK); /* return OK */ mClGetError: if (pClBlk != NULL) _endClBlkFree (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 _endClPoolIdGet ( 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 + -