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

📄 zbuflib.c

📁 vxworks的完整的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* zbufLib.c - zbuf interface library *//* Copyright 1984 - 2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01h,07may02,kbw  man page edits01g,15oct01,rae  merge from truestack ver 01g, base 01f (AE / 5_X)01f,26jan95,jdi  format tweak.01e,24jan95,rhp  revisions based on jdi feedback01d,16jan95,rhp  fix SEE ALSO subroutine ref format01c,15nov94,dzb  doc tweaks.01b,09nov94,rhp  library man page added, subroutine man pages edited.01a,08nov94,dzb  written.*//*DESCRIPTIONThis library contains routines to create, build, manipulate, anddelete zbufs.  Zbufs, also known as "zero copy buffers," are a dataabstraction designed to allow software modules to share bufferswithout unnecessarily copying data.To support the data abstraction, the subroutines in this library hidethe implementation details of zbufs.  This also maintains thelibrary's independence from any particular implementation mechanism,thus permitting the zbuf interface to be used with other buffering schemes.Zbufs have three essential properties.  First, a zbuf holds asequence of bytes.  Second, these bytes are organized into one or moresegments of contiguous data, although the successive segmentsthemselves are not usually contiguous.  Third, the data within asegment may be shared with other segments; that is, the data may be in useby more than one zbuf at a time.ZBUF TYPESThe following data types are used in managing zbufs:.iP ZBUF_ID 16 3An arbitrary (but unique) integer that identifies a particular zbuf..iP ZBUF_SEGAn arbitrary (but unique within a single zbuf) integer that identifiesa segment within a zbuf..LPADDRESSING BYTES IN ZBUFSThe bytes in a zbuf are addressed by the combination <zbufSeg>,<offset>.  The <offset> may be positive or negative, and is simply thenumber of bytes from the beginning of the segment <zbufSeg>.A <zbufSeg> can be specified as NULL, to identify the segment at thebeginning of a zbuf.  If <zbufseg> is NULL, <offset> is theabsolute offset to any byte in the zbuf.  However, it is moreefficient to identify a zbuf byte location relative to the <zbufSeg>that contains it; see zbufSegFind() to convert any <zbufSeg>, <offset>pair to the most efficient equivalent.Negative <offset> values always refer to bytes before thecorresponding <zbufSeg>, and are not usually the most efficientaddress formulation (though using them may save yourprogram other work in some cases).The following special <offset> values, defined as constants,allow you to specify the very beginning or the very end of an entire zbuf,regardless of the <zbufSeg> value:.iP ZBUF_BEGIN 16 3The beginning of the entire zbuf..iP ZBUF_ENDThe end of the entire zbuf (useful for appending to a zbuf; see below)..LPINSERTION AND LIMITS ON OFFSETSAn <offset> is not valid if it points outside the zbuf.  Thus, toaddress data currently within an N-byte zbuf, the valid offsetsrelative to the first segment are 0 through N-1.Insertion routines are a special case: they obey the usualconvention, but they use <offset> to specify where the new databegins after the insertion is complete.  Therefore, the originalzbuf data is always inserted just before the bytelocation addressed by the <offset> value.  The value of thisconvention is that it permits inserting (or concatenating) data eitherbefore or after the existing data.  To insert before all the datacurrently in a zbuf segment, use 0 as <offset>.  To insert after allthe data in an N-byte segment, use N as <offset>. An <offset> of N-1inserts the data just before the last byte in an N-byte segment.An <offset> of 0 is always a valid insertion point; for an empty zbuf,0 is the only valid <offset> (and NULL the only valid <zbufSeg>).SHARING DATAThe routines in this library avoid copying segment data wheneverpossible.  Thus, by passing and manipulating ZBUF_IDs rather thancopying data, multiple programs can communicate with greaterefficiency.  However, each program must be aware of data sharing:changes to the data in a zbuf segment are visible to all zbuf segmentsthat reference the data.To alter your own program's view of zbuf data without affecting otherprograms, first use zbufDup() to make a new zbuf; then you can use aninsertion or deletion routine, such as zbufInsertBuf(), to add asegment that only your program sees (until you pass a zbuf containingit to another program).  It is safest to do all direct datamanipulation in a private buffer, before enrolling it in a zbuf: inprinciple, you should regard all zbuf segment data as shared.Once a data buffer is enrolled in a zbuf segment, the zbuf library isresponsible for noticing when the buffer is no longer in use by anyprogram, and freeing it.  To support this, zbufInsertBuf() requiresthat you specify a callback to a free routine each time you build azbuf segment around an existing buffer.  You can use this callback to notifyyour application when a data buffer is no longer in use.VXWORKS AE PROTECTION DOMAINSUnder VxWorks AE, this feature is restricted to the kernel protection domain.  This restriction does not apply under non-AE versions of VxWorks.  To use this feature, include the following component:INCLUDE_ZBUF_SOCKSEE ALSOzbufSockLibINTERNALExtensions:zbufJoin (zbufId, zbufSeg) - coalesce two adjacent segment fragments    This routine combines two or more contiguous zbuf segments into a single    zbuf segment.  Such an operation is only feasible for joining segments    that have the same freeRtn and freeArg, and that follow eachother in    the zbuf.  This could be useful for coalescing zbuf segments fragmented    by split operations.zbufOwn (zbufId, zbufSeg, offset, len) - own a local copy of zbuf data    This routine makes a local copy of a portion of a zbuf.  This    is useful if you want to change the actual data in a zbuf, but want to    make sure that you are not corrupting another zbuf that shares the    same data.  If you are the only zbuf segment using a particular buffer,    this routine does nothing.  If other zbufs reference the same data, this    routine inserts a copy of the requested data, then deletes reference    to the original data.*//* includes */#include "vxWorks.h"#include "zbufLib.h"#include "stdlib.h"#include "memPartLib.h"/* locals *//* * N.B. * As other back-ends to zbuf are ever developed, and need to be run * concurrently with existing back-ends, the zbufFunc table needs to have * the back-end resident function table pointer in the ZBUF_ID.  This will * require a modification to the current method of simply passing through * the ZBUF_ID to the back-end.  Instead, the ZBUF_ID will have to point * to a structure, which would contain the back-end function table pointer * and a back-end-specific XX_ID pointer. */LOCAL ZBUF_FUNC		zbufFuncNull =	/* null funcs for unconnected zbufs */    {    NULL,				/* zbufCreate()		*/    NULL,				/* zbufDelete()		*/    NULL,				/* zbufInsert()		*/    NULL,				/* zbufInsertBuf()	*/    NULL,				/* zbufInsertCopy()	*/    NULL,				/* zbufExtractCopy()	*/    NULL,				/* zbufCut()		*/    NULL,				/* zbufSplit()		*/    NULL,				/* zbufDup()		*/    NULL,				/* zbufLength()		*/    NULL,				/* zbufSegFind()	*/    NULL,				/* zbufSegNext()	*/    NULL,				/* zbufSegPrev()	*/    NULL,				/* zbufSegData()	*/    NULL				/* zbufSegLength()	*/    };LOCAL ZBUF_FUNC *	pZbufFunc = &zbufFuncNull;/********************************************************************************* zbufLibInit - initialize the zbuf interface library** This routine initializes the zbuf interface facility.  It* must be called before any zbuf routines are used.  This routine is* typically called during the initialization of a VxWorks facility which* uses or extends the zbuf interface, although this is not a requirement.* The zbuf library may be used on its own, provided an appropriate back-end* buffer mechanism is available, and is specified by <libInitRtn>.** RETURNS:* OK, or ERROR if the zbuf interface cannot be initialized.** NOMANUAL*/STATUS zbufLibInit    (    FUNCPTR		libInitRtn	/* back-end buffer mechanism init rtn */    )    {    ZBUF_FUNC *		pZbufFuncTemp;	/* temp return of back-end func table */    /* call the back-end initialization routine - watch for NULL func ptr */    if ((libInitRtn == NULL) || ((pZbufFuncTemp =	(ZBUF_FUNC *) (libInitRtn) ()) == NULL))	return (ERROR);    pZbufFunc = pZbufFuncTemp;			/* connect back-end func tbl */    return (OK);    }#if	FALSE		/* Pool routines not in service yet *//********************************************************************************* zbufSegPoolCreate - create an empty zbuf segment pool** This routine creates a zbuf segment pool.  It remains empty (that is, does* not contain any free segments) until segments are added by calling* zbufSegPoolAdd().  Operations performed on zbuf segments pools require* a zbuf segment pool ID, which is returned by this routine.** RETURNS:* A zbuf segment pool ID, or NULL if an ID cannot be created.** SEE ALSO: zbufSegPoolDelete(), zbufSegPoolAdd()** NOMANUAL*/ZBUF_POOL_ID zbufSegPoolCreate (void)    {    ZBUF_POOL_ID	zbufPoolId;		/* new ID */        if ((zbufPoolId = (ZBUF_POOL_ID) KHEAP_ALLOC(sizeof(struct zbufPoolId))) ==	NULL)	return (NULL);				/* malloc pool ID struct */    /* create mutex sem for guarding access to zbuf segment pool */    if ((zbufPoolId->poolSem = semMCreate ((SEM_Q_PRIORITY |	SEM_INVERSION_SAFE | SEM_DELETE_SAFE))) == ERROR)	{	KHEAP_FREE(zbufPoolId);			/* free resources */	return (NULL);	}    /* create binary sem for waiting for free segments to come into pool */    if ((zbufPoolId->waitSem = semBCreate (SEM_Q_PRIORITY, SEM_EMPTY)) == ERROR)	{        semDelete (zbufPoolId->poolSem);	/* free resources */	KHEAP_FREE(zbufPoolId);	return (NULL);	}    zbufPoolId->use = 0;			/* no loaned buffers yet */    zbufPoolId->blockHead = NULL;		/* no blocks/segs yet */    return (zbufPoolId);    }/********************************************************************************* zbufSegPoolDelete - delete a zbuf segment pool and free associated segments** This routine will free any segments associated with <zbufPoolId>,* then delete the zbuf segment pool ID itself.  To do this, all segments* must be in the pool (that is, no segments may currently be part of a zbuf).* <zbufPoolId> must not be used after this routine executes successfully.** Associated segments will be returned to the system memory pool if they* were allocated with zbufSegPoolAdd().  No action will be taken upon* user segments added to the segment pool by specifying the segment block* start address. These segments should be considered free after this* routine executes successfully.* * RETURNS:* OK, or ERROR if the zbuf segment pool has outstanding segments.** SEE ALSO: zbufSegPoolCreate(), zbufSegPoolAdd()** NOMANUAL*/STATUS zbufSegPoolDelete    (    ZBUF_POOL_ID	zbufPoolId	/* zbuf segment pool to delete */    )    {    ZBUF_BLOCK_ID	zbufBlock;		/* ptr to block headers */    ZBUF_BLOCK_ID	zbufBlockTemp;		/* temp storage of block hdr */    /* obtain exclusive access to zbuf segment pool structures */    if ((semTake (zbufPoolId->poolSem, WAIT_FOREVER)) == ERROR)	return (ERROR);    if (zbufPoolId->use != 0)			/* any segments in use ? */	{	semGive (zbufPoolId->poolSem);		/* give up access */	return (ERROR);				/* cannot feee if in use */	}    /* go through list of block headers, freein all alloc'ed mem */    for (zbufBlock = zbufPoolId->blockHead; zbufBlock != NULL;)	{	zbufBlockTemp = zbufBlock->blockNext;		KHEAP_FREE(zbufBlock);			/* free each hdr & memory */        zbufBlock = zbufBlockTemp;		/* bump to next block hdr */        }    semDelete (zbufPoolId->waitSem);		/* free wait binary sem */    semDelete (zbufPoolId->poolSem);		/* free pool mutex sem */    KHEAP_FREE(zbufPoolId);			/* free actual pool ID struct */    return (OK);    }/********************************************************************************* zbufSegPoolAdd - add a block of zbuf segments to a zbuf segment pool** This routine adds a block of zbuf segments to <zbufPoolId>.  This routine* may be called multiple times to add segment blocks of different sizes and* numbers.** The segment size <segSise> will be rounded up to the memory allignment* requirements of the target architecture.  The minimum size of a* segment is the size of a void pointer.** If system memory is to be used for the segment allocation, set <blockStart>* to NULL, in which case <blockLength> parameter will be ignored.* Otherwise, a block of memory to be used may be specified by <blockStart> and* <blockLen>.  If a segment block is specified with <blockStart>, the* <segNum> parameter is ignored.  Instead, the number of alligned segments* that can be obtained from <memLength> are added to the pool.* * If a zbuf segment pool is deleted with zbufSegPoolDelete(), any allocated* segment blocks will be returned to the system memory pool.  Specific memory* blocks obtained through <blockStart> should be considered free after* zbufSegPoolDelete() executes successfully, but the user will not be* given any further indication of the memory being released from the pool.* * RETURNS:* OK, or ERROR if the zbuf segment block cannot be added to the pool.** SEE ALSO: zbufSegPoolDelete()** NOMANUAL*/STATUS zbufSegPoolAdd    (    ZBUF_POOL_ID	zbufPoolId,	/* pool to add zbuf segments to */    int			segSize,	/* size of new segments */    int			segNum,		/* number of new segs (system memory) */    caddr_t		blockStart,	/* start of seg block (user memory) */    int			blockLen	/* length of seg block (user memory) */    )    {    ZBUF_BLOCK_ID	zbufBlockNew;		/* new block header */    ZBUF_BLOCK_ID 	zbufBlock = NULL;	/* location to insert new hdr */    STATUS		status = ERROR;		/* return value */    int			ix;			/* counter for block init */    /* obtain exclusive access to zbuf segment pool structures */    if ((semTake (zbufPoolId->poolSem, WAIT_FOREVER)) == ERROR)	return (ERROR);    /* adjust segSize for mem allign - must be at least void * (see below) */    segSize = min (MEM_ROUND_UP(segSize), sizeof (void *));    if (blockStart == NULL)			/* if allocating from system */	{

⌨️ 快捷键说明

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