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

📄 zbuflib.c

📁 vxworks的完整的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	if ((zbufBlockNew = (ZBUF_BLOCK_ID) KHEAP_ALLOC((sizeof(struct zbufBlockId)	    + (segSize * segNum)))) == NULL)	/* allocate hdr and seg block */	    goto release;	blockStart = (caddr_t) (zbufBlockNew + 1);/* set start of seg block */        }    else					/* use supplied user memory */	{        /* calc the number of segments that can be obtained from user mem */	if ((segNum = blockLen / segSize) == 0)	/* must be at least one */	    goto release;        if ((zbufBlockNew = (ZBUF_BLOCK_ID) KHEAP_ALLOC	    (sizeof(struct zbufBlockId))) == NULL)/* allocate block hdr only */	    goto release;	}    zbufBlockNew->length = segSize;		/* block is for "segSize" */    zbufBlockNew->zbufPoolId = zbufPoolId;	/* for _zbufSegPoolFree() */    zbufBlockNew->segFree = (void *) blockStart;/* first seg in block is free */    /*     * Go through block, and divide up into segNum number of segments.     * The first location of each segment points to the next free segment,     * with the last segment pointing to NULL.  In this way, a sll of free     * segments is kept, with the pointer in the segment memory itself.     */    for (ix = 1; ix < segNum; ix++, blockStart += segSize)	*((void **) blockStart) = (void *) (blockStart + segSize);    *((void **) blockStart) = NULL;    /* find the proper location in the pool to insert the new seg block */    if ((zbufPoolId->blockHead != NULL) &&        (zbufPoolId->blockHead->length < segSize))	{        zbufBlock = zbufPoolId->blockHead;        for (; zbufBlock->blockNext != NULL; zbufBlock = zbufBlock->blockNext)	    if (zbufBlock->blockNext->length >= segSize)	        break;        }    if (zbufBlock == NULL)			/* insert new block at start */	{	zbufBlockNew->blockNext = zbufPoolId->blockHead;/* new to first */        zbufPoolId->blockHead = zbufBlockNew;	/* head to new */	}    else					/* insert in middle or end */	{	zbufBlockNew->blockNext = zbufBlock->blockNext;	/* new to next */	zbufBlock->blockNext = zbufBlockNew;	/* prev to new */	}    status = OK;				/* done! */release:					/* error encountered */    semGive (zbufPoolId->poolSem);		/* give up access */    return (status);    }/********************************************************************************* _zbufSegPoolFree - return a zbuf segment to a zbuf segment pool** This routine returns a zbuf segment to a zbuf segment pool.* To return <buf> to the zbuf segment block that it was originally allocated* from, place the segment <buf> at the start of the segment block associated* with <zbufBlockId>.  If <zbufBlockId> is NULL, the segment <buf> was* allocated from system memory, and should be returned with free().** RETURNS: N/A.** NOMANUAL*/void _zbufSegPoolFree     (    caddr_t		buf,		/* zbuf segment to return */    ZBUF_BLOCK_ID	zbufBlockId	/* seg block to return <buf> to */    )    {    ZBUF_POOL_ID	zbufPoolId;		/* back pointer to pool ID */    if (zbufBlockId == NULL)			/* if originally malloc'ed */	KHEAP_FREE(buf);    else					/* else return to pool */	{	zbufPoolId = zbufBlockId->zbufPoolId;	/* obtain back pointer to ID */	/* obtain exclusive access to zbuf segment pool structures */        if ((semTake (zbufPoolId->poolSem, WAIT_FOREVER)) == ERROR)	    return;        *((void **) buf) = zbufBlockId->segFree;/* hook my next to first */	zbufBlockId->segFree = (void *) buf;	/* hook head to me */        zbufPoolId->use--;			/* check it in */        semFlush (zbufPoolId->waitSem);		/* free those waiting for seg */        semGive (zbufPoolId->poolSem);		/* give up access */	}    }/********************************************************************************* zbufInsertPool - obtain a segment and insert into a zbuf** This routine obtains a zbuf segment from <zbufPoolId> and* inserts it into zbuf <zbufId> at the specified location.  The requested* segment is not initialized (that is, it is not zeroed out) by this routine.* * This routine searches <zbufPoolId> looking for a suitably sized free* segment.  The smallest free segment that is at least <len> bytes in length* is obtained and inserted into <zbufId>.  If no free segments are found,* this routine will pend for <timeout> ticks waiting for a zbuf segment to be* released from another zbuf.  As segments are released from other zbufs,* they are examined to see if they are at least <len> bytes.  If they are* not suitable, the timeout is reset to <timeout> ticks, and this routine* will pend again waiting for a segment to be released.** If <zbufPoolId> is NULL, the system memory pool is used to allocate a* segment of <len> bytes.  Upon release of this segment from the zbuf, it* will returned to the system memory pool.** The location of insertion is specified by <zbufSeg> and <offset>.  See* the zbufLib manual page for more information on specifying* a byte location within a zbuf.  In particular, insertion within* a zbuf occurs before the byte location specified by <zbufSeg> and <offset>.* Additionally, <zbufSeg> and <offset> must be NULL and 0,* respectively, when inserting into an empty zbuf.** RETURNS:* The zbuf segment ID of the inserted segment,* or NULL if the operation fails.** NOMANUAL*/ZBUF_SEG zbufInsertPool    (    ZBUF_POOL_ID	zbufPoolId,	/* pool to obtain zbuf segment from */    ZBUF_ID		zbufId,		/* zbuf to insert segment into */    ZBUF_SEG		zbufSeg,	/* zbuf segment base for <offset> */    int			offset,		/* relative byte offset */    int			len,		/* requested segment length in bytes */    int			timeout		/* timeout in ticks */    )    {    ZBUF_BLOCK_ID 	zbufBlock = NULL;	/* segment block header */    caddr_t		buf = NULL;		/* requested segment buf */    int			lenLast = NULL;		/* last seg block length seen */    if (zbufPoolId == NULL)			/* alloc from system mem */	if ((buf = KHEAP_ALLOC(len)) == NULL)	    return (NULL);    /* if not allocating from system memory, try to obtain from seg pool */    while (buf == NULL)	        {	/* obtain exclusive access to zbuf segment pool structures */        if ((semTake (zbufPoolId->poolSem, timeout)) == ERROR)	    return (NULL);        /*         * Search the pool's seg blocks headers for a suitable size (first fit)         * and that has free segments attached to it.  An over-sized segment	 * will be taken if no more suitably sized segments are available.	 * No fragmentation is performed.  A segment remains whole.	 * If no segments are available (right-fit or oversized), pend on	 * waitSem for segment to come in from _zbufSegPoolFree().         */        zbufBlock = zbufPoolId->blockHead;        for (; zbufBlock != NULL; zbufBlock = zbufBlock->blockNext)            if (((lenLast = zbufBlock->length) >= len) &&		(zbufBlock->segFree != NULL))                break;        if (zbufBlock == NULL)	    {	    /* going to pend or exit, so give up access */            semGive (zbufPoolId->poolSem);	    /* check that there are seg blocks large enough for len */            if ((lenLast == NULL) || (lenLast < len))		return (NULL);            /* wait for segments to come back in... */	    if ((semTake (zbufPoolId->waitSem, timeout)) == ERROR)	        return (NULL);	    }        else					/* found suitable segment */	    {	    buf = (caddr_t) zbufBlock->segFree;	/* segment is first */	    zbufBlock->segFree = *((void **) buf); /* first is next */            zbufPoolId->use++;			/* check it out */            semGive (zbufPoolId->poolSem);	/* give up access */	    }        }    /* insert the new segment into zbufId at the specified location */    if ((zbufSeg = zbufInsertBuf (zbufId, zbufSeg, offset,	buf, len, _zbufSegPoolFree, (int) zbufBlock)) == NULL)	_zbufSegPoolFree (buf, zbufBlock);	/* free seg on failure */    return (zbufSeg);    }#endif		/* FALSE *//********************************************************************************* zbufCreate - create an empty zbuf** This routine creates a zbuf, which remains empty (that is, it contains* no data) until segments are added by the zbuf insertion routines.* Operations performed on zbufs require a zbuf ID, which is returned by* this routine.** VXWORKS AE PROTECTION DOMAINS* Under VxWorks AE, you can call this function from within the kernel * protection domain only.  In addition, the returned ID is valid within * the kernel protection domain only.  This restriction does not apply * under non-AE versions of VxWorks.  ** RETURNS:* A zbuf ID, or NULL if a zbuf cannot be created.** SEE ALSO: zbufDelete()*/ZBUF_ID zbufCreate (void)    {    return ((pZbufFunc->createRtn == NULL) ? NULL :	(ZBUF_ID) (pZbufFunc->createRtn) ());    }/********************************************************************************* zbufDelete - delete a zbuf** This routine deletes any zbuf segments in the specified zbuf, then* deletes the zbuf ID itself.  <zbufId> must not be used after this routine* executes successfully.** For any data buffers that were not in use by any other zbuf, zbufDelete()* calls the associated free routine (callback).** VXWORKS AE PROTECTION DOMAINS* Under VxWorks AE, you can call this function from within the kernel * protection domain only.  In addition, all arguments to this function can  * reference only that data which is valid in the kernel protection domain. * This restriction does not apply under non-AE versions of VxWorks.  ** RETURNS:* OK, or ERROR if the zbuf cannot be deleted.** SEE ALSO: zbufCreate(), zbufInsertBuf()*/STATUS zbufDelete    (    ZBUF_ID		zbufId		/* zbuf to be deleted */    )    {    return ((pZbufFunc->deleteRtn == NULL) ? ERROR :	(pZbufFunc->deleteRtn) (zbufId));    }/********************************************************************************* zbufInsert - insert a zbuf into another zbuf** This routine inserts all <zbufId2> zbuf segments into <zbufId1> at the* specified byte location.** The location of insertion is specified by <zbufSeg> and <offset>.  See* the zbufLib manual page for more information on specifying* a byte location within a zbuf.  In particular, insertion within* a zbuf occurs before the byte location specified by <zbufSeg> and <offset>.* Additionally, <zbufSeg> and <offset> must be NULL and 0,* respectively, when inserting into an empty zbuf.** After all the <zbufId2> segments are inserted into <zbufId1>, the zbuf ID* <zbufId2> is deleted.  <zbufId2> must not be used after this routine* executes successfully.** VXWORKS AE PROTECTION DOMAINS* Under VxWorks AE, you can call this function from within the kernel * protection domain only.  In addition, all arguments to this function can  * reference only that data which is valid in the kernel protection domain. * Likewise, the returned ZBUF_SEG is valid within the kernel protection * domain only.  This restriction does not apply under non-AE versions of * VxWorks.  ** RETURNS:* The zbuf segment ID for the first inserted segment,* or NULL if the operation fails.*/ZBUF_SEG zbufInsert    (    ZBUF_ID		zbufId1,	/* zbuf to insert <zbufId2> into */    ZBUF_SEG		zbufSeg,	/* zbuf segment base for <offset> */    int			offset,		/* relative byte offset */    ZBUF_ID		zbufId2		/* zbuf to insert into <zbufId1> */    )    {    return ((pZbufFunc->insertRtn == NULL) ? NULL :        (ZBUF_SEG) (pZbufFunc->insertRtn) (zbufId1, zbufSeg, offset, zbufId2));    }/********************************************************************************* zbufInsertBuf - create a zbuf segment from a buffer and insert into a zbuf** This routine creates a zbuf segment from the application buffer <buf>* and inserts it at the specified byte location in <zbufId>.** The location of insertion is specified by <zbufSeg> and <offset>.  See* the zbufLib manual page for more information on specifying* a byte location within a zbuf.  In particular, insertion within* a zbuf occurs before the byte location specified by <zbufSeg> and <offset>.* Additionally, <zbufSeg> and <offset> must be NULL and 0,* respectively, when inserting into an empty zbuf.** The parameter <freeRtn> specifies a free-routine callback that runs when* the data buffer <buf> is no longer referenced by any zbuf segments.  If* <freeRtn> is NULL, the zbuf functions normally, except that the* application is not notified when no more zbufs segments reference <buf>.* The free-routine callback runs from the context of the task that last* deletes reference to the buffer.  Declare the <freeRtn> callback as* follows (using whatever routine name suits your application):* .CS*	void freeCallback*	    (*	    caddr_t	buf,	/@ pointer to application buffer @/*	    int		freeArg	/@ argument to free routine @/*	    )* .CE** VXWORKS AE PROTECTION DOMAINS* Under VxWorks AE, you can call this function from within the kernel * protection domain only.  In addition, all arguments to this function can  * reference only that data which is valid in the kernel protection domain. * This restriction does not apply under non-AE versions of VxWorks.  ** RETURNS:* The zbuf segment ID of the inserted segment,* or NULL if the operation fails.*/ZBUF_SEG zbufInsertBuf    (    ZBUF_ID		zbufId,		/* zbuf in which buffer is inserted */    ZBUF_SEG		zbufSeg,	/* zbuf segment base for <offset> */    int			offset,		/* relative byte offset */    caddr_t		buf,		/* application buffer for segment */    int			len,		/* number of bytes to insert */    VOIDFUNCPTR		freeRtn,	/* free-routine callback */    int			freeArg		/* argument to free routine */    )    {    return ((pZbufFunc->insertBufRtn == NULL) ? NULL :	(ZBUF_SEG) (pZbufFunc->insertBufRtn) (zbufId, zbufSeg, offset,	buf, len, freeRtn, freeArg));    }/********************************************************************************* zbufInsertCopy - copy buffer data into a zbuf** This routine copies <len> bytes of data from the application buffer <buf>* and inserts it at the specified byte location in <zbufId>.  The* application buffer is in no way tied to the zbuf after this operation;* a separate copy of the data is made.

⌨️ 快捷键说明

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