⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netbuflib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    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);    }/********************************************************************************* _clusterGet - 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 * _clusterGet    (    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 */    level = intLock (); 			/* lock interrupts briefly */    if (pClPool->pClHead == NULL)		/* return if no buffers */        {        intUnlock (level);        return (NULL);        }    pClBuf = pClPool->pClHead;			/* update the head */    if ((pClPool->pClHead = pClBuf->pClNext) == NULL)        {	/* update the pool Mask */        pNetPool->clMask &= ~(CL_LOG2_TO_CL_SIZE(pClPool->clLg2));        }    pClPool->clNumFree--; 			/* decrement the free count */    pClPool->clUsage++;				/* increment the usage count */    intUnlock (level);    return ((char *)pClBuf);    }/********************************************************************************* mClGet - 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 _mClGet    (    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 */    )    {    int			log2Size;	/* size of cluster to the base 2 */    CL_POOL_ID 		pClPool; 	/* pointer to the cluster pool */    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 */    /* check pMblk */    if ((pMblk == NULL) || ((pClBlk = _clBlkGet (pNetPool, canWait)) == NULL))	goto mClGetError;    /* check the boundary conditions */    if (bufSize > pNetPool->clSizeMax)	{	if (bestFit)            {            errno = S_netBufLib_CLSIZE_INVALID;	    goto mClGetError;            }	else	    log2Size = pNetPool->clLg2Max;	}    else if (bufSize < pNetPool->clSizeMin)	log2Size = pNetPool->clLg2Min;    else	{	log2Size = SIZE_TO_LOG2(bufSize);	if (bufSize > CL_LOG2_TO_CL_SIZE(log2Size))	    log2Size++;	}    /* get the appropriate pool pointer */    if ((pClPool = pNetPool->clTbl [CL_LOG2_TO_CL_INDEX (log2Size)]) == NULL)	{#ifdef NETBUF_DEBUG	logMsg ("mClGet: 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 (pClPool->pClHead == NULL)        {        /* pool has max clusters, find best fit or close fit */        if (pNetPool->clMask >= CL_LOG2_TO_CL_SIZE(pClPool->clLg2))            {	/* first fetch a cluster with a closest bigger size */            bufSize  = CL_LOG2_TO_CL_SIZE(pClPool->clLg2);            log2Size = pClPool->clLg2;            while (bufSize <= CL_SIZE_MAX)                {                if (pNetPool->clMask & bufSize)                    {                    pClPool = pNetPool->clTbl [CL_LOG2_TO_CL_INDEX (log2Size)];                    break;                    }                bufSize <<= 1;                log2Size ++;                }            }        /* if close fit then find closest lower size */        else if (!bestFit && pNetPool->clMask)            {            pClPool = pNetPool->clTbl [CL_SIZE_TO_CL_INDEX(pNetPool->clMask)];            }        else if (canWait == M_WAIT)	/* want for buffers */            {            if (_pNetBufCollect)                {                intUnlock (ms);                (*_pNetBufCollect) (pNetPool->pPoolStat);		canWait = M_DONTWAIT;                goto reTry;                }            }        }    if ((pClBuf = pClPool->pClHead))	{	/* if this is the last cluster available set the mask */	if ((pClPool->pClHead = pClBuf->pClNext) == NULL)            {	    pNetPool->clMask &= ~(CL_LOG2_TO_CL_SIZE(pClPool->clLg2));            }	pClPool->clNumFree--;	pClPool->clUsage++;        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	  = pClPool->clSize;    pClBlk->pClFreeRtn	  = NULL;    pClBlk->clRefCnt	  = 1;    pMblk->pClBlk 	  = pClBlk;    return (OK); 		/* return OK */    mClGetError:    if (pClBlk != NULL)        _clBlkFree (pClBlk);    return (ERROR); 		/* return ERROR */    }/********************************************************************************* clPoolIdGet - 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 _clPoolIdGet    (    NET_POOL_ID		pNetPool,	/* pointer to the net pool */    int 		bufSize,	/* size of the buffer */    BOOL		bestFit		/* TRUE/FALSE */    )    {    int			log2Size;    if (bufSize > pNetPool->clSizeMax)	{	log2Size = pNetPool->clLg2Max;	if (bestFit)	    return (NULL);	}    else if (bufSize < pNetPool->clSizeMin)        {	log2Size = pNetPool->clLg2Min;        }    else	{	log2Size = SIZE_TO_LOG2(bufSize);	if (bufSize > CL_LOG2_TO_CL_SIZE(log2Size))	    log2Size++;	}    return (pNetPool->clTbl [CL_LOG2_TO_CL_INDEX(log2Size)]);    }/********************************************************************************* netBufLibInit - initialize netBufLib** This routine executes during system startup if INCLUDE_NETWORK is defined* when the image is built. It links the network buffer library into the image.** RETURNS: OK or ERROR.**/STATUS netBufLibInit (void)    {    return (OK);    }/********************************************************************************* netPoolInit - initialize a netBufLib-managed memory pool** Call this routine to set up a netBufLib-managed memory* pool.  Within this pool, netPoolInit() organizes several sub-pools: one* for `mBlk' structures, one for `clBlk' structures, and as many cluster* sub-pools are there are cluster sizes.  As input, this routine expects* the following parameters:* .IP <pNetPool> 15* Expects a NET_POOL_ID that points to a previously allocated NET_POOL* structure.  You need not initialize any values in this structure.  That* is handled by netPoolInit().* .IP <pMclBlkConfig>* Expects a pointer to a previously allocated and initialized M_CL_CONFIG* structure.  Within this structure, you must provide four* values: 'mBlkNum', a count of `mBlk' structures; 'clBlkNum', a count* of `clBlk' structures; 'memArea', a pointer to an area of memory* that can contain all the `mBlk' and `clBlk' structures; and 'memSize', * the size of that memory area.  For example, you can set up an M_CL_CONFIG * structure as follows:* .CS*     M_CL_CONFIG mClBlkConfig = /@ mBlk, clBlk configuration table @/*         {*         mBlkNum     clBlkNum        memArea         memSize*         ----------  ----            -------         -------*         400,        245,            0xfe000000,     21260*         };* .CE* You can * calculate the 'memArea' and 'memSize' values.  Such code could first * define a table as shown above, but set both 'memArea' and 'memSize' * as follows:* .CS* mClBlkConfig.memSize = (mClBlkConfig.mBlkNum * (M_BLK_SZ + sizeof(long))) +*                        (mClBlkConfig.clBlkNum * CL_BLK_SZ);* .CE* You can set the memArea value to a pointer to private memory, or you can* reserve the memory with a call to malloc().  For example:* .CS*     mClBlkConfig.memArea = malloc(mClBlkConfig.memSize);* .CE** The netBufLib.h file defines M_BLK_SZ as:* .CS*     sizeof(struct mBlk)* .CE* Currently, this evaluates to 32 bytes.  Likewise, this file * defines CL_BLK_SZ as:* .CS *     sizeof(struct clBlk)* .CE* Currently, this evaluates to 32 bytes. ** When choosing values for 'mBlkNum' and 'clBlkNum', remember that you need * as many `clBlk' structures as you have clusters (data buffers).  You also * need at least as many `mBlk' structures as you have `clBlk' structures, but * you will most likely need more. * That is because netBufLib shares buffers by letting multiple `mBlk' * structures join to the same `clBlk' and thus to its underlying cluster.  * The `clBlk' keeps a count of the number of `mBlk' structures that * reference it.  ** .IP <pClDescTbl>* Expects a pointer to a table of previously allocated and initialized CL_DESC* structures.  Each structure in this table describes a single cluster pool.* You need a dedicated cluster pool for each cluster size you want to support.* Within each CL_DESC structure, you must provide four values: 'clusterSize',* the size of a cluster in this cluster pool; 'num', the number of clusters * in this cluster pool; 'memArea', a pointer to an area of memory that can * contain all the clusters; and 'memSize', the size of that memory area.* * Thus, if you need to support six different cluster sizes, this parameter* must point to a table containing six CL_DESC structures.  For example,* consider the following:* .CS*     CL_DESC clDescTbl [] =   /@ cluster descriptor table @/*         {*         /@*         clusterSize        num     memArea         memSize*         ----------         ----    -------         -------*         @/*         {64,               100,    0x10000,        6800},*         {128,              50,     0x20000,        6600},*         {256,              50,     0x30000,        13000},*         {512,              25,     0x40000,        12900},*         {1024,             10,     0x50000,        10280},*         {2048,             10,     0x60000,        20520}*         };* .CE* As with the 'memArea' and 'memSize' members in the M_CL_CONFIG structure,* you can set these members of the CL_DESC structures by calculation after* you create the table.  The formula would be as follows:* .CS*     clDescTbl[n].memSize = *         (clDescTbl[n].num * (clDescTbl[n].clusterSize + sizeof(long)));* .CE* The 'memArea' member can point to a private memory area that you know to be * available for storing clusters, or you can use malloc().* .CS*     clDescTbl[n].memArea =  malloc( clDescTbl[n].memSize ); * .CE** Valid cluster sizes range from 64 bytes to 65536 bytes.  If there are * multiple cluster pools, valid sizes are further restricted to powers of* two (for example, 64, 128, 256, and so on).  If there is only one cluster * pool (as is often the case for the memory pool specific to a single * device driver), there is no power of two restriction.  Thus, the cluster * can be of any size between 64 bytes and 65536 bytes on 4-byte alignment.  A * typical buffer size for Ethernet devices is 1514 bytes.  However, because* a cluster size requires a 4-byte alignment, the cluster size for this * Ethernet buffer would have to be increased to at least 1516 bytes.* * .IP <clDescTblNumEnt>* Expects a count of the elements in the CL_DESC table referenced by * the <pClDescTbl> parameter.  This is a count of the number of cluster* pools.  You can get this value using the NELEMENTS macro defined  * in vxWorks.h.  For example:* .CS*     int clDescTblNumEnt = (NELEMENTS(clDescTbl));* .CE* .IP <pFuncTbl>* Expects a NULL or a pointer to a function table.  This table contains * pointers to the functions used to manage the buffers in this memory pool.  * Using a NULL for this parameter tells netBufLib to use its default function * table.  If you opt for the default function table, every `mBlk' and * every cluster is prepended by a 4-byte header (which is why the size * calculations above for clusters and `mBlk' structures contained an * extra 'sizeof(long)').  However, users need not concern themselves * with this header when accessing these buffers.  The returned pointers * from functions such as netClusterGet() return pointers to the start of* data, which is just after the header.  * .LP

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -