📄 netbuflib.c
字号:
int num, /* number of units to allocate */ char * pool /* pre allocated memory area */ ) { M_BLK_ID pMblk = NULL; int ix; int size; /* size of each unit */ M_BLK_ID * ppMblk; size = M_BLK_SZ + sizeof (void *); /* accomodate for netPoolId */ ppMblk = &pMblk; for (ix = 0; ix < num; ++ix) { *ppMblk = (M_BLK_ID) (pool + sizeof (void *)); *((NET_POOL_ID *)(pool)) = pNetPool; (*ppMblk)->mBlkHdr.mType = MT_FREE; ppMblk = &((*ppMblk)->mBlkHdr.mNext); pool += size; } return (pMblk); }/********************************************************************************* _clBlkCarve - carve up the clBlk pool.** This function carves the the clBlks from a pre allocated pool.** RETURNS: CL_BLK_ID or NULL.** NOMANUAL*/LOCAL CL_BLK_ID _clBlkCarve ( int num, /* number of units to allocate */ char * pool /* pre allocated memory area */ ) { CL_BLK_ID pClBlk = NULL; int ix; CL_BLK_ID * ppClBlk; ppClBlk = &pClBlk; for (ix = 0; ix < num; ++ix) { *ppClBlk = (CL_BLK_ID) (pool); ppClBlk = &((*ppClBlk)->clNode.pClBlkNext); pool += CL_BLK_SZ; } return (pClBlk); }/********************************************************************************* _clPoolCarve - carve up the cluster pool** This function carves the clusters from a pre allocated pool.* Each cluster maintains an 4 byte header info. This header info contains* a place to hold the pointer to the cluster pool.* This header info is prepended to the cluster buffer* and is hidden from the user. The header info is used at the time of* freeing the cluster. This function returns the pointer the cluster buffer* chain.** RETURNS: CL_BUF_ID or NULL.** NOMANUAL*/LOCAL CL_BUF_ID _clPoolCarve ( CL_POOL_ID pClPool, /* pointer to the cluster pool */ int num, /* number of units to allocate */ int clSize, /* cluster size */ char * pool /* pre allocated memory area */ ) { CL_BUF_ID pClBuf = NULL; /* pointer to cluster buffer */ FAST int ix; /* counter */ CL_BUF_ID * ppClBuf; /* ptr to ptr to cluster buffer */ clSize += sizeof (void *); /* make space for pool pointer */ ppClBuf = &pClBuf; for (ix = 0; ix < num; ++ix) { *ppClBuf = (CL_BUF_ID) (pool + sizeof (void *)); *((CL_POOL_ID *) (pool)) = pClPool; ppClBuf = &((*ppClBuf)->pClNext); pool += clSize; } return (pClBuf); }/********************************************************************************* _memPoolInit - initialize the memory** This function initialized the memory passed to it.** RETURNS: OK or ERROR.** NOMANUAL*/LOCAL STATUS _memPoolInit ( 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); }/********************************************************************************* _mBlkFree - free the given mBlk** This function frees the given mBlk and returns it to the mBlk pool.** RETURNS: N/A** NOMANUAL*/LOCAL void _mBlkFree ( 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); }/********************************************************************************* _clBlkFree - 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 _clBlkFree ( 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 = CL_BUF_TO_CL_POOL (pClBuf); pClBuf->pClNext = pClPool->pClHead; pClPool->pClHead = pClBuf; /* update mask */ pClPool->pNetPool->clMask |= CL_LOG2_TO_CL_SIZE(pClPool->clLg2); 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); }/********************************************************************************* _clFree - 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 _clFree ( NET_POOL_ID pNetPool, /* pointer to the net pool */ char * pClBuf /* pointer to the cluster buffer */ ) { CL_POOL_ID pClPool; FAST int level; pClPool = CL_BUF_TO_CL_POOL (pClBuf); level = intLock (); ((CL_BUF_ID)pClBuf)->pClNext = pClPool->pClHead; pClPool->pClHead = (CL_BUF_ID)pClBuf; /* update mask */ pClPool->pNetPool->clMask |= CL_LOG2_TO_CL_SIZE(pClPool->clLg2); pClPool->clNumFree++; intUnlock (level); }/********************************************************************************* _mBlkClFree - 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 _mBlkClFree ( 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); _mBlkFree (pNetPool, pMblk); /* free the mBlk */ return (pMblkNext); }/********************************************************************************* _mBlkGet - 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 _mBlkGet ( 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); }/********************************************************************************* _clBlkGet - 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 _clBlkGet ( 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -