📄 ixosbuflib.c
字号:
/* ixBufLib.c - network buffer library *//* Copyright 1984 - 2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history-------------------- - adapt from netBufLib.c - cache line alignement - tune for optimal performances *//*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 "logLib.h"#include "IxOsBufLib.h"/* defines */#undef NETBUF_DEBUG/* mBlk size */#define MBLK_SIZE ROUND_UP((M_BLK_SZ + sizeof(long)), \ _CACHE_ALIGN_SIZE)/* cLBlk size */#define CLBLK_SIZE ROUND_UP(CL_BLK_SZ, _CACHE_ALIGN_SIZE)/* global */IMPORT VOIDFUNCPTR _pNetBufCollect; /* protocol specific routine *//* extern */IMPORT int ffsMsb ();/* forward declarations */LOCAL STATUS ixAlignedPoolInit (NET_POOL_ID pNetPool, M_CL_CONFIG *pMclBlkConfig, CL_DESC *pClDescTbl, int clDescTblNumEnt, BOOL fromKheap);LOCAL M_BLK_ID ixMBlkCarve (NET_POOL_ID pNetPool, int num, char * pool);LOCAL CL_BLK_ID ixClBlkCarve (int num, char * pool);LOCAL CL_BUF_ID ixClPoolCarve (CL_POOL_ID pClPool, int num, int clSize, char * pool);LOCAL STATUS ixMemPoolInit (int num, int unitSize, int headerSize, char * memArea);LOCAL void ixMBlkFree (NET_POOL_ID pNetPool, M_BLK_ID pMblk);LOCAL void ixClBlkFree (CL_BLK_ID pClBlk);LOCAL void ixClusterFree (NET_POOL_ID pNetPool, char * pClBuf);LOCAL M_BLK_ID ixMBlkClFree (NET_POOL_ID pNetPool, M_BLK_ID pMblk);LOCAL M_BLK_ID ixMBlkGet (NET_POOL_ID pNetPool, int canWait, UCHAR type);LOCAL CL_BLK_ID ixClBlkGet (NET_POOL_ID pNetPool, int canWait);LOCAL char * ixClusterGet (NET_POOL_ID pNetPool, CL_POOL_ID pClPool);LOCAL STATUS ixMClGet (NET_POOL_ID pNetPool, M_BLK_ID pMblk, int bufSize, int canWait, BOOL bestFit);LOCAL CL_POOL_ID ixClPoolIdGet (NET_POOL_ID pNetPool, int bufSize, BOOL bestFit);LOCAL POOL_FUNC ixFuncTbl = /* pool function table */ { ixAlignedPoolInit, ixMBlkFree, ixClBlkFree, ixClusterFree, ixMBlkClFree, ixMBlkGet, ixClBlkGet, ixClusterGet, ixMClGet, ixClPoolIdGet, };/* * 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 * _pIxOsBufLibPoolFuncTbl = &ixFuncTbl;/******************************************************************* * Get the amount of memory required to create * an aligned buff pool */UINT32ixAlignedPoolDataSize(int count, int size){ return _CACHE_ALIGN_SIZE + count * ROUND_UP(size, _CACHE_ALIGN_SIZE);}/* Get the amount of memory required to create * an aligned buff pool */UINT32 ixAlignedPoolMbufSize(int count){ return _CACHE_ALIGN_SIZE + (count * MBLK_SIZE) + _CACHE_ALIGN_SIZE + (count * CLBLK_SIZE);}/************************************************************************ * ixAlignedPoolInit - initialize the net pool** This function initializes a net pool** RETURNS: OK or ERROR.** NOMANUAL*/LOCAL STATUS ixAlignedPoolInit ( 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 (ignored) */ ) { CL_DESC * pClDesc; /* pointer to the cluster descriptor */ int clBufSize; /* size of the buff after alignment */ int requiredMemory; char * memArea; if (clDescTblNumEnt != 1) { return ERROR; } bzero ((char *) pNetPool->clTbl, sizeof (pNetPool->clTbl)); if ((pNetPool->pPoolStat = (M_STAT *) calloc (1, sizeof (M_STAT))) == NULL) return (ERROR); pNetPool->pmBlkHead = NULL; if (pMclBlkConfig != NULL) /* if mbuf config is specified */ { requiredMemory = _CACHE_ALIGN_SIZE + (pMclBlkConfig->mBlkNum * MBLK_SIZE) + _CACHE_ALIGN_SIZE + (pMclBlkConfig->clBlkNum * CLBLK_SIZE); if (pMclBlkConfig->memSize < requiredMemory) { errno = S_netBufLib_MEMSIZE_INVALID; goto poolInitError; } /* initialize the memory pool */ if (ixMemPoolInit (pMclBlkConfig->mBlkNum, M_BLK_SZ, sizeof(void *), pMclBlkConfig->memArea ) != OK) { goto poolInitError; } /* carve up the mBlk pool */ pNetPool->pmBlkHead = ixMBlkCarve ( 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 + _CACHE_ALIGN_SIZE + (pMclBlkConfig->mBlkNum * MBLK_SIZE)); if (pMclBlkConfig->clBlkNum > 0) { /* initialize the memory pool */ if (ixMemPoolInit (pMclBlkConfig->clBlkNum,CLBLK_SIZE,0,memArea) != OK) goto poolInitError; pNetPool->pClBlkHead = ixClBlkCarve ( pMclBlkConfig->clBlkNum, memArea ); if (pNetPool->pClBlkHead == NULL) goto poolInitError; } } pClDesc = pClDescTbl; /* arrange buf size to deal with 32 bytes alignment */ clBufSize = ROUND_UP(pClDesc->clSize, _CACHE_ALIGN_SIZE); if (pClDesc->clSize < 64) {#ifdef NETBUF_DEBUG logMsg ("poolInit -- Invalid cluster size\n", 0, 0, 0, 0, 0, 0);#endif /* NETBUF_DEBUG */ errno = S_netBufLib_CLSIZE_INVALID; goto poolInitError; } if ((pNetPool->clTbl[0] = (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[0]->clSize = pClDesc->clSize; pNetPool->clTbl[0]->pNetPool = pNetPool; requiredMemory = _CACHE_ALIGN_SIZE + pClDesc->clNum * clBufSize; if (pClDesc->memSize < requiredMemory) { errno = S_netBufLib_MEMSIZE_INVALID; goto poolInitError; } if (ixMemPoolInit (pClDesc->clNum, clBufSize, 0, pClDesc->memArea) != OK) { goto poolInitError; } pNetPool->clTbl[0]->pClHead = ixClPoolCarve (pNetPool->clTbl[0], pClDesc->clNum, clBufSize, (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); }/********************************************************************************* ixMBlkCarve - 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 ixMBlkCarve ( 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; M_BLK_ID * ppMblk; ppMblk = &pMblk; /* align the mblks on a 32 byte boundary */ pool = (char *)(ROUND_UP((unsigned int)pool + sizeof (void *), _CACHE_ALIGN_SIZE)) - sizeof (void *); 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 += MBLK_SIZE; } *ppMblk = NULL; return (pMblk); }/********************************************************************************* ixClBlkCarve - 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 ixClBlkCarve ( 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; } *ppClBlk = NULL; return (pClBlk); }/********************************************************************************* ixClPoolCarve - 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 ixClPoolCarve ( 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 */ ppClBuf = &pClBuf; /* align the clusters on a 32 byte boundary */ pool = (char *)(ROUND_UP((unsigned int)pool, _CACHE_ALIGN_SIZE)); for (ix = 0; ix < num; ix++) { *ppClBuf = (CL_BUF_ID) (pool); ppClBuf = &((*ppClBuf)->pClNext); pool += clSize; } *ppClBuf = NULL; return (pClBuf); }/********************************************************************************* ixMemPoolInit - initialize the memory** This function initialized the memory passed to it.** RETURNS: OK or ERROR.** NOMANUAL*/LOCAL STATUS ixMemPoolInit ( 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));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -