📄 netbuflib.c
字号:
/* netBufLib.c - network buffer library *//* Copyright 1984 - 2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01r,07may02,kbw man page edits01q,15oct01,rae merge from truestack ver 01w, base 01n (SPR #65195 etc.)01p,08feb01,kbw fixing a man page format problem01o,07feb01,spm removed unused garbage collection code; updated documentation01n,26aug98,fle doc : fixed a proc header trouble with netPoolInit01m,25aug98,n_s M_WAIT will only call _pNetBufCollect 1 time. spr #2210401l,12dec97,kbw making minor man page fixes01k,11dec97,vin added netMblkOffsetToBufCopy part of SPR 9563.01j,08dec97,vin added netMblkChainDup() SPR 9966.01i,05dec97,vin changed netMblkClFree to netMblkFree in netTupleGet()01h,03dec97,vin added netTupleGet() SPR 9955, added some unsupported routines 01g,13nov97,vin code clean up.01f,25oct97,kbw making minor man page fixes01e,08oct97,vin corrected clBlkFree()01d,06oct97,vin fixed a man page.01c,30sep97,vin changed MSIZE to M_BLK_SZ.01b,19sep97,vin added cluster Blks, fixed bugs, removed reference count pointers.01a,08aug97,vin written.*//*DESCRIPTIONThis library contains routines that you can use to organize and maintaina memory pool that consists of pools of `mBlk' structures, pools of `clBlk'structures, and pools of clusters. The `mBlk' and `clBlk' structuresare used to manage the clusters. The clusters are containers for the datadescribed by the `mBlk' and `clBlk' structures.These structures and the various routines of this library constitute abuffering API that has been designed to meet the needs both of network protocols and network device drivers. The `mBlk' structure is the primary vehicle for passing data betweena network driver and a protocol. However, the `mBlk' structure mustfirst be properly joined with a `clBlk' structure that was previouslyjoined with a cluster. Thus, the actual vehicle for passing data isnot merely an `mBlk' structure but an `mBlk'-`clBlk'-clusterconstruct. To use this feature, include the following component:INCLUDE_NETWRS_NETBUFLIBINCLUDE FILES: netBufLib.hINTERNAL ------------ |mBlk | |manages | |clusterBlk | | | | | ------------|\ ------------- \ |clBlk | \ |manages the| \ |cluster. | \|clRefCnt=1 | ------------| \ \ \ ------------| \|Cluster | | | | | | | | | |-------------Two mBlks sharing the same cluster:----------------------------------- -----------| |-----------| | mBlk | | mBlk | | | | | | | | | | | | | | | | | |-----------\ /-----------| \ / \ / \ / \|------------|/ | clBlk | | | |clRefCnt = 2| | | | | |------------\ \ |---------------| | cluster | | | | | |---------------|*//* includes */#include "vxWorks.h"#include "stdlib.h"#include "intLib.h"#include "string.h"#include "semaphore.h"#include "memLib.h"#include "errnoLib.h"#include "netBufLib.h"#include "private/semLibP.h"#include "memPartLib.h"/* Virtual Stack Support */#ifdef VIRTUAL_STACK#include "netinet/vsLib.h"#endif/* defines */#undef NETBUF_DEBUG#ifdef NETBUF_DEBUG#include "logLib.h"#endif /* NETBUF_DEBUG */#define FROM_KHEAP 1 /* let _poolInit() use KHEAP_ALLOC */#define FROM_HOMEPDHEAP 0 /* let _poolInit() use calloc() */ /* global */VOIDFUNCPTR _pNetBufCollect = NULL; /* protocol specific routine *//* extern */IMPORT int ffsMsb ();/* forward declarations */LOCAL STATUS _poolInit (NET_POOL_ID pNetPool, M_CL_CONFIG * pMclBlkConfig, CL_DESC * pClDescTbl, int clDescTblNumEnt, BOOL fromKheap);LOCAL M_BLK_ID _mBlkCarve (NET_POOL_ID pNetPool, int num, char * pool);LOCAL CL_BLK_ID _clBlkCarve (int num, char * pool);LOCAL CL_BUF_ID _clPoolCarve (CL_POOL_ID pClPool, int num, int clSize, char * pool);LOCAL STATUS _memPoolInit (int num, int unitSize, int headerSize, char * memArea);LOCAL void _mBlkFree (NET_POOL_ID pNetPool, M_BLK_ID pMblk);LOCAL void _clBlkFree (CL_BLK_ID pClBlk);LOCAL void _clFree (NET_POOL_ID pNetPool, char * pClBuf);LOCAL M_BLK_ID _mBlkClFree (NET_POOL_ID pNetPool, M_BLK_ID pMblk);LOCAL M_BLK_ID _mBlkGet (NET_POOL_ID pNetPool, int canWait, UCHAR type);LOCAL CL_BLK_ID _clBlkGet (NET_POOL_ID pNetPool, int canWait);LOCAL char * _clusterGet (NET_POOL_ID pNetPool, CL_POOL_ID pClPool);LOCAL STATUS _mClGet (NET_POOL_ID pNetPool, M_BLK_ID pMblk, int bufSize, int canWait, BOOL bestFit);LOCAL CL_POOL_ID _clPoolIdGet (NET_POOL_ID pNetPool, int bufSize, BOOL bestFit);LOCAL POOL_FUNC dfltFuncTbl = /* default pool function table */ { _poolInit, _mBlkFree, _clBlkFree, _clFree, _mBlkClFree, _mBlkGet, _clBlkGet, _clusterGet, _mClGet, _clPoolIdGet, };/* * this is a global pointer to a function table provided as a back door * for users who want to use a different allocation scheme for defaults * By initializing this _pNetPoolFuncTbl at runtime before initialization of * the network stack, one can change the default function table. The system * pools use the default function table. */ POOL_FUNC * _pNetPoolFuncTbl = &dfltFuncTbl;/******************************************************************************** * _poolInit - initialize the net pool** This function initializes a net pool** RETURNS: OK or ERROR.** NOMANUAL*/LOCAL STATUS _poolInit ( NET_POOL_ID pNetPool, /* pointer to a net pool */ M_CL_CONFIG * pMclBlkConfig, /* pointer to mBlk,clBlk config */ CL_DESC * pClDescTbl, /* pointer to cluster desc table */ int clDescTblNumEnt, /* number of cluster desc entries */ BOOL fromKheap /* 1:KHEAP_ALLOC 0:malloc/calloc */ ) { int ix; /* index variable */ int iy; /* index variable */ int log2Size; /* cluster size to the base 2 */ CL_DESC * pClDesc; /* pointer to the cluster descriptor */ CL_POOL * pClPool; /* pointer to the cluster pool */ char * memArea; bzero ((char *) pNetPool->clTbl, sizeof (pNetPool->clTbl)); if (fromKheap) { if ((pNetPool->pPoolStat = (M_STAT *) KHEAP_ALLOC(sizeof (M_STAT))) == NULL) return (ERROR); bzero ((char *)pNetPool->pPoolStat, sizeof (M_STAT)); } else { if ((pNetPool->pPoolStat = (M_STAT *) calloc (1, sizeof (M_STAT))) == NULL) return (ERROR); } pNetPool->pmBlkHead = NULL; if (pMclBlkConfig != NULL) /* if mbuf config is specified */ { if (pMclBlkConfig->memSize < ((pMclBlkConfig->mBlkNum * (M_BLK_SZ + sizeof(long))) + (pMclBlkConfig->clBlkNum * CL_BLK_SZ))) { errno = S_netBufLib_MEMSIZE_INVALID; goto poolInitError; } /* initialize the memory pool */ if (_memPoolInit (pMclBlkConfig->mBlkNum, M_BLK_SZ, sizeof(void *), pMclBlkConfig->memArea ) != OK) { goto poolInitError; } /* carve up the mBlk pool */ pNetPool->pmBlkHead = _mBlkCarve ( pNetPool, pMclBlkConfig->mBlkNum, pMclBlkConfig->memArea ); /* increment free mBlks and number of mBlks */ pNetPool->mBlkCnt = pMclBlkConfig->mBlkNum; pNetPool->mBlkFree = pMclBlkConfig->mBlkNum; pNetPool->pPoolStat->mTypes [MT_FREE] = pMclBlkConfig->mBlkNum; pNetPool->pPoolStat->mNum = pMclBlkConfig->mBlkNum; memArea = (char * )((int)pMclBlkConfig->memArea + (pMclBlkConfig->mBlkNum * (M_BLK_SZ + sizeof(long)))); if (pMclBlkConfig->clBlkNum > 0) { /* initialize the memory pool */ if (_memPoolInit (pMclBlkConfig->clBlkNum, CL_BLK_SZ, 0, memArea) != OK) goto poolInitError; pNetPool->pClBlkHead = _clBlkCarve ( pMclBlkConfig->clBlkNum, memArea ); if (pNetPool->pClBlkHead == NULL) goto poolInitError; } } /* initialize clusters */ pNetPool->clMask = 0; pNetPool->clLg2Max = 0; pNetPool->clLg2Min = 0; for (pClDesc = pClDescTbl, ix = 0 ; (pClDesc != NULL) && (pClDesc->clNum > 0) && (ix < clDescTblNumEnt); ix++, pClDesc++) { /* range check cluster type */ if ((pClDesc->clSize < CL_SIZE_MIN) || (pClDesc->clSize > CL_SIZE_MAX)) {#ifdef NETBUF_DEBUG logMsg ("poolInit -- Invalid cluster type\n", 0, 0, 0, 0, 0, 0);#endif /* NETBUF_DEBUG */ errno = S_netBufLib_CLSIZE_INVALID; goto poolInitError; } log2Size = SIZE_TO_LOG2(pClDesc->clSize); pNetPool->clMask |= CL_LOG2_TO_CL_SIZE(log2Size); /* set the mask */ if ((pNetPool->clLg2Max == 0) && (pNetPool->clLg2Min == 0)) { pNetPool->clLg2Min = log2Size; pNetPool->clLg2Max = log2Size; } pNetPool->clLg2Max = max(log2Size, pNetPool->clLg2Max); pNetPool->clLg2Min = min(log2Size, pNetPool->clLg2Min); pNetPool->clSizeMax = CL_LOG2_TO_CL_SIZE(pNetPool->clLg2Max); pNetPool->clSizeMin = CL_LOG2_TO_CL_SIZE(pNetPool->clLg2Min); if (fromKheap) { if ((pClPool = (CL_POOL *) KHEAP_ALLOC(sizeof(CL_POOL))) == NULL) {#ifdef NETBUF_DEBUG logMsg ("poolInit -- cluster pool allocation\n", 0, 0, 0, 0, 0, 0);#endif /* NETBUF_DEBUG */ errno = S_netBufLib_NO_SYSTEM_MEMORY; goto poolInitError; } bzero ((char *)pClPool, sizeof (CL_POOL)); } else { if ((pClPool = (CL_POOL *) calloc (1, sizeof(CL_POOL))) == NULL) {#ifdef NETBUF_DEBUG logMsg ("poolInit -- cluster pool allocation\n", 0, 0, 0, 0, 0, 0);#endif /* NETBUF_DEBUG */ errno = S_netBufLib_NO_SYSTEM_MEMORY; goto poolInitError; } } pNetPool->clTbl [CL_LOG2_TO_CL_INDEX(log2Size)] = pClPool; for (iy = (log2Size - 1); ((!(pNetPool->clMask & CL_LOG2_TO_CL_SIZE(iy))) && (CL_LOG2_TO_CL_INDEX(iy) >= CL_INDX_MIN)) ; iy--) { pNetPool->clTbl [CL_LOG2_TO_CL_INDEX(iy)] = pClPool; } pClPool->clSize = pClDesc->clSize; pClPool->clLg2 = log2Size; pClPool->pNetPool = pNetPool; /* initialize the back pointer */ if (pClDesc->memSize < (pClDesc->clNum * (pClDesc->clSize + sizeof(int)))) { errno = S_netBufLib_MEMSIZE_INVALID; goto poolInitError; } if (_memPoolInit (pClDesc->clNum, pClDesc->clSize, sizeof (void *) , pClDesc->memArea) != OK) goto poolInitError; pClPool->pClHead = _clPoolCarve (pClPool, pClDesc->clNum, pClDesc->clSize, pClDesc->memArea); if (pClPool->pClHead == NULL) { goto poolInitError; } pClPool->clNum = pClDesc->clNum; pClPool->clNumFree = pClDesc->clNum; } return (OK); poolInitError: netPoolDelete (pNetPool); return (ERROR); }/********************************************************************************* _mBlkCarve - carve up the mBlk pool.** This function carves the the mBlks from a pre allocated pool.** RETURNS: M_BLK_ID or NULL.** NOMANUAL*/LOCAL M_BLK_ID _mBlkCarve ( NET_POOL_ID pNetPool, /* pointer to net pool */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -