?? endnetbuflib.c
字號:
/* endNetBufLib.c - network buffer library *//* Copyright 1984 - 2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01c,20nov03,m_h initialize pClBlk to NULL01b,27mar03,rcs removed sizeof(long) from endMemPoolInit() for cluster pool. SPR# 8734301a,23jan03,rcs 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.h*//* 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 "netinet/if_ether.h"#include "memPartLib.h"#include "endLib.h"/* Virtual Stack Support */#ifdef VIRTUAL_STACK#include "netinet/vsLib.h"#endif/* defines */#define 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() */ #define END_CLUSTER_SIZE 1536#define END_CLUSTER_LOG (ffsMsb((END_CLUSTER_SIZE)) - 1)#define END_CLUSTER_MASK (1 << (END_CLUSTER_LOG))typedef struct end_cl_pool { CL_POOL clPool; UINT32 * clFreeArray; } END_CL_POOL; /* global */IMPORT VOIDFUNCPTR _pNetBufCollect; /* protocol specific routine */CL_BUF_ID lastClHead;CL_POOL_ID pEndPoolId;/* extern */IMPORT int ffsMsb ();/* forward declarations */LOCAL STATUS _endPoolInit (NET_POOL_ID pNetPool, M_CL_CONFIG * pMclBlkConfig, CL_DESC * pClDescTbl, int clDescTblNumEnt, BOOL fromKheap);LOCAL M_BLK_ID _endMBlkCarve (NET_POOL_ID pNetPool, int num, char * pool);LOCAL CL_BLK_ID _endClBlkCarve (int num, char * pool);LOCAL CL_BUF_ID _endClPoolCarve (CL_POOL_ID pClPool, int num, int clSize, char * pool);LOCAL STATUS _endMemPoolInit (int num, int unitSize, int headerSize, char * memArea);LOCAL void _endMBlkFree (NET_POOL_ID pNetPool, M_BLK_ID pMblk);LOCAL void _endClBlkFree (CL_BLK_ID pClBlk);LOCAL void _endClFree (NET_POOL_ID pNetPool, char * pClBuf);LOCAL M_BLK_ID _endMBlkClFree (NET_POOL_ID pNetPool, M_BLK_ID pMblk);LOCAL M_BLK_ID _endMBlkGet (NET_POOL_ID pNetPool, int canWait, UCHAR type);LOCAL CL_BLK_ID _endClBlkGet (NET_POOL_ID pNetPool, int canWait);LOCAL char * _endClusterGet (NET_POOL_ID pNetPool, CL_POOL_ID pClPool);LOCAL STATUS _endMClGet (NET_POOL_ID pNetPool, M_BLK_ID pMblk, int bufSize, int canWait, BOOL bestFit);LOCAL CL_POOL_ID _endClPoolIdGet (NET_POOL_ID pNetPool, int bufSize, BOOL bestFit);LOCAL POOL_FUNC dfltFuncTbl = /* default pool function table */ { _endPoolInit, _endMBlkFree, _endClBlkFree, _endClFree, _endMBlkClFree, _endMBlkGet, _endClBlkGet, _endClusterGet, _endMClGet, _endClPoolIdGet, };/* * 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 * _pEndNetPoolFuncTbl = &dfltFuncTbl;/******************************************************************************** * _endPoolInit - initialize the net pool** This function initializes a net pool** RETURNS: OK or ERROR.** NOMANUAL*/LOCAL STATUS _endPoolInit ( 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 */ ) { CL_DESC * pClDesc; /* pointer to the cluster descriptor */ char * memArea; END_CL_POOL * pEndClPool; 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 + 1) * MBLK_SIZE) + ((pMclBlkConfig->clBlkNum + 1) * CLBLK_SIZE))) { errno = S_netBufLib_MEMSIZE_INVALID; goto poolInitError; } /* initialize the memory pool */ if (_endMemPoolInit (pMclBlkConfig->mBlkNum, M_BLK_SZ, sizeof(void *), pMclBlkConfig->memArea ) != OK) { goto poolInitError; } /* carve up the mBlk pool */ pNetPool->pmBlkHead = _endMBlkCarve ( 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 * MBLK_SIZE) + sizeof(long)); if (pMclBlkConfig->clBlkNum > 0) { /* initialize the memory pool */ if (_endMemPoolInit (pMclBlkConfig->clBlkNum,CLBLK_SIZE,0,memArea) != OK) goto poolInitError; pNetPool->pClBlkHead = _endClBlkCarve ( pMclBlkConfig->clBlkNum, memArea ); if (pNetPool->pClBlkHead == NULL) goto poolInitError; } } pClDesc = pClDescTbl; pNetPool->clMask = 0; pNetPool->clLg2Max = 0; pNetPool->clLg2Min = 0; /* range check cluster type */ if (pClDesc->clSize < END_CLUSTER_SIZE) {#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; } if (fromKheap) { if ((pNetPool->clTbl[0] = (CL_POOL *)KHEAP_ALLOC(sizeof(END_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 *)pNetPool->clTbl[0], sizeof (END_CL_POOL)); } else { if ((pNetPool->clTbl[0] = (CL_POOL *)calloc(1,sizeof(END_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; } } pEndClPool = (END_CL_POOL *)pNetPool->clTbl[0]; if ((pEndClPool->clFreeArray = (UINT32 *) malloc((sizeof(UINT32 *) * (pClDesc->clNum + 1)))) == NULL) { errno = S_netBufLib_NO_SYSTEM_MEMORY; goto poolInitError; } pNetPool->clTbl[0]->clSize = pClDesc->clSize; pNetPool->clTbl[0]->pNetPool = pNetPool; if (pClDesc->memSize < (pClDesc->clNum * pClDesc->clSize)) { errno = S_netBufLib_MEMSIZE_INVALID; goto poolInitError; } if (_endMemPoolInit (pClDesc->clNum, pClDesc->clSize, 0 , pClDesc->memArea) != OK) { goto poolInitError; } pNetPool->clTbl[0]->pClHead = _endClPoolCarve (pNetPool->clTbl[0], pClDesc->clNum, pClDesc->clSize, (char *)pClDesc->memArea); if (pNetPool->clTbl[0]->pClHead == NULL) { goto poolInitError; } pNetPool->clTbl[0]->clNum = pClDesc->clNum; pNetPool->clTbl[0]->clNumFree = pClDesc->clNum; return (OK); poolInitError: netPoolDelete (pNetPool); return (ERROR); }/********************************************************************************* _endMBlkCarve - 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 _endMBlkCarve ( NET_POOL_ID pNetPool, /* pointer to net pool */ 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 = MBLK_SIZE; /* 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); }/********************************************************************************* _endClBlkCarve - 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 _endClBlkCarve ( 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 += CLBLK_SIZE; } return (pClBlk); }/********************************************************************************* _endClPoolCarve - 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 _endClPoolCarve ( 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 */ CL_BUF_ID pClLast; /* ptr for last cluster buffer */ END_CL_POOL * pEndClPool; pEndClPool = (END_CL_POOL *) pClPool; ppClBuf = &pClBuf; for (ix = 0; ix < num; ix++) { pEndClPool->clFreeArray[ix + 1] = (UINT32)ppClBuf; pEndClPool->clFreeArray[0] = ix; *ppClBuf = (CL_BUF_ID) (pool); *((CL_POOL_ID *) (pool)) = pClPool; ppClBuf = &((*ppClBuf)->pClNext); if (ix == (num - 1)) { pClLast = (CL_BUF_ID)pool; pClLast->pClNext = NULL; } pool += clSize; } return (pClBuf); }/********************************************************************************* _endMemPoolInit - initialize the memory** This function initialized the memory passed to it.** RETURNS: OK or ERROR.** NOMANUAL*/LOCAL STATUS _endMemPoolInit (
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -