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

📄 rbufflib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    )    {    if (OBJ_VERIFY (rBuff, rBuffClassId) == OK)	/* validate rBuff ID */        {	return (OK);        }    else	{	return (ERROR);	}    }/********************************************************************************* rBuffWrite - Write data to a ring of buffers** This routine writes data to an extendable ring of buffers. If the existing* structure is full, and the existing number of buffers is less than the* specified minimum, then this function will attempt to add another buffer to* the ring.** This function may be called from interrupt level.** Mutually exclusive access must be guaranteed by the caller.** NOMANUAL*/UINT8* rBuffWrite    (    BUFFER_ID buffId,		/* ring buffer id */    UINT8 *   pDummy,		/* not used for WV ring buffer */    UINT32    numOfBytes	/* number of bytes to reserve */    )    {    BOOL startUploading;    RBUFF_ID rBuff;			/* access this particular rBuff */    UINT8 *returnPtr = (UINT8 *) ~0; /* Return a non-zero value if OK */    /* Get access to the private members of this buffer's descriptor. */    rBuff = (RBUFF_ID) buffId;    /* Get out early if this request makes no sense. */    if (numOfBytes > rBuff->info.buffSize)        {        return (NULL);        }    /* Critical Region Start */    if (rBuff->info.dataContent >= rBuff->info.threshold)        {        startUploading = TRUE;        }    else        {        startUploading = FALSE;        }    if (rBuff->buffWrite->spaceAvail >= numOfBytes)        {        /* Record the start of the reserved area */        returnPtr = rBuff->dataWrite;        /*         *  If we are consuming one of our precious empty buffs,         *  check we have enough in reserve.         */        if (rBuff->buffWrite->dataLen == 0)             {            --rBuff->info.emptyBuffs;	    }	if (rBuff->info.emptyBuffs < RBUFF_EMPTY_KEEP &&            rBuff->info.currBuffs != rBuff->info.maxBuffs)            {            /* Schedule the rBuff Mgr to extend the buffer */            RBUFF_SEND_MSG (RBUFF_MSG_ADD, MSG_PRI_URGENT, rBuff, 0);	    }        rBuff->buffWrite->dataLen    += numOfBytes;        rBuff->dataWrite             += numOfBytes;        rBuff->buffWrite->spaceAvail -= numOfBytes;        /*         *  It may be that the current buffer is full at this point,         *  but don't do anything about it yet as the situation will         *  be handled next time through. Also, it's possible that         *  the current buffer may even have been emptied by then.         */        }    else        {        /*         *  Data won't fit in this buffer (at least not entirely),         *  is the next buffer available?         */        if (rBuff->buffWrite->next == rBuff->buffRead)            {            /*  We've caught the reader. This will only happen when             *  we have actually filled the maximum allocation of             *  buffers *or* the reserved buffer has been filled             *  before the buffer has had the opportunity to             *  be extended. We cannot extend the buffer at this point             *  as we may be in a critical region, the design is such             *  that if the buffer could be extended it should have             *  been done by now (for that matter, the wrap-around             *  should have also occurred).             *             *  If we have filled the reserved buffer without having             *  the opportunity to extend the buffer then the buffer             *  is configured badly and must be retuned.             *             *  Meanwhile, at this moment, options are:             *             *  1) If we have filled the entire buffer and cannot wrap-             *     around then return ERROR.             *  2) If we have filled the entire buffer but can wrap-             *     around then do that.             */                       if (rBuff->info.options & RBUFF_WRAPAROUND)                {                /*                 *  OK, perform an inline ring extension supplying NULL                 *  as the new buffer forcing the ring to wrap-around.                 *  This is a deterministic action.                 */                /* Interrupts already locked out */                rBuffAdd(rBuff, NULL);                }            else                {                /* Oh dear, can't wrap-round */            	RBUFF_SEND_MSG (RBUFF_MSG_FULL, MSG_PRI_NORMAL, rBuff, 0);		wvEvtBufferFullNotify = TRUE;                return (NULL);                }            }        /*         *  OK.         *  In the case that this function is writing the data, it         *  can be shared between this and next buffer.         *  In the case that we are only reserving the space, we must         *  return a pointer to contiguous space and therefore skip the         *  remainder of the previous buffer.         */        /* skip the remainder of the current buffer */        rBuff->buffWrite->spaceAvail = 0;        /* Move on to the next buffer */        rBuff->buffWrite = rBuff->buffWrite->next;        /* Record the start of the reserved area */        returnPtr = rBuff->buffWrite->dataStart;        /* Point dataWrite past the reserved area */        rBuff->dataWrite = rBuff->buffWrite->dataStart;        rBuff->buffWrite->dataLen    = numOfBytes;        rBuff->dataWrite            += numOfBytes;        rBuff->buffWrite->spaceAvail =            rBuff->info.buffSize - numOfBytes;        if (--rBuff->info.emptyBuffs < RBUFF_EMPTY_KEEP &&            rBuff->info.currBuffs != rBuff->info.maxBuffs)            {            /* Schedule the rBuff Mgr to extend the buffer */            RBUFF_SEND_MSG (RBUFF_MSG_ADD, MSG_PRI_URGENT, rBuff, 0);            }        }    rBuff->info.dataContent  += numOfBytes;    /* update info */    if(rBuff->info.dataContent > rBuff->info.bytesPeak)        {        rBuff->info.bytesPeak = rBuff->info.dataContent;        }    rBuff->info.bytesWritten += numOfBytes;    rBuff->info.writesSinceReset++;    if (!startUploading && rBuff->info.dataContent >= rBuff->info.threshold)        {        rBuff->info.timesXThreshold++;        if (!(rBuff->info.options & RBUFF_UP_DEFERRED))            {            /*             *  Signal for uploading to begin. Note that if we have just             *  reserved space it is imperative that uploading does not             *  actually begin until the data is in the buffer.             */#if (CPU_FAMILY == I80X86)            portWorkQAdd1 ((FUNCPTR)semBGiveDefer,                (int) &rBuff->buffDesc.threshXSem);#else            workQAdd1 ((FUNCPTR)semBGiveDefer,                (int) &rBuff->buffDesc.threshXSem);#endif            }        }    /* Critical Region End */    return (returnPtr);    }/********************************************************************************* rBuffRead - Read data from a ring of buffers** This routine reads data from an extendable ring of buffers.** This function assumes mutually exclusive access is guaranteed by the caller.** NOMANUAL*/INT32 rBuffRead    (    BUFFER_ID 	buffId,		/* generic buffer descriptor */    UINT8 *   	dataDest,    UINT32  	numOfBytes    )    {    UINT32 	bytesToCopy;    UINT32	remaining = numOfBytes;    RBUFF_ID 	rBuff;		/* access private members of this rBuff desc */    /* Get access to the private members of this particular rBuff. */    rBuff = (RBUFF_ID) buffId;    /* Critical Region Start */    while (remaining > 0)        {        bytesToCopy = (rBuff->buffRead->dataLen < remaining ?                        rBuff->buffRead->dataLen : remaining);        if (bytesToCopy > 0)            {            memcpy (dataDest,rBuff->dataRead,bytesToCopy);            remaining                -= bytesToCopy;            dataDest                 += bytesToCopy;            /* Update buffer */            rBuff->buffRead->dataLen -= bytesToCopy;            rBuff->dataRead          += bytesToCopy;            rBuff->info.dataContent  -= bytesToCopy;            }        if (rBuff->buffRead->dataLen != 0)            {            /* This buffer is now empty */            rBuffHandleEmpty (rBuff);            }        else            {            /* this buffer is not yet emptied */            rBuff->dataRead += bytesToCopy;            }        }    /* update info */    rBuff->info.bytesRead += (numOfBytes - remaining);    rBuff->info.readsSinceReset++;    /* Critical Region End */    return (numOfBytes - remaining);    }/********************************************************************************* rBuffReadReserve - Return the number of contiguous bytes available for*                    reading.** NOMANUAL*/UINT32 rBuffReadReserve    (    BUFFER_ID buffId,		/* generic identifier for this buffer */    UINT8 **src    )    {    RBUFF_ID rBuff;		/* specific identifier for this rBuff */    INT32 bytesAvailable;     /* Get access to the private members of this particular rBuff. */    rBuff = (RBUFF_ID) buffId;    /* Generate and return the available contiguous bytes. */    if ((bytesAvailable = rBuff->buffRead->dataLen))        {        *src = rBuff->dataRead;        }    else        {        *src = NULL;        }    return (bytesAvailable);    }/********************************************************************************* rBuffReadCommit - Move the read data ptr along a ring of buffers** This routine moves the data ptr along a ring of buffers.** It is equivalent to reading data from the buffers and should be used* when the data has been copied elsewhere.** This function assumes mutually exclusive access is guaranteed by the caller.** NOMANUAL*/STATUS rBuffReadCommit    (    BUFFER_ID buffId,		/* generic identifier for this buffer */    UINT32  numOfBytes    )    {    RBUFF_ID rBuff;		/* specific identifier for this rBuff */    /* Get access to the private members of this particular rBuff. */    if (!numOfBytes)    {        return (OK);    }    rBuff = (RBUFF_ID) buffId;    /* Critical Region Start */    if (numOfBytes == rBuff->buffRead->dataLen)        {        rBuffHandleEmpty (rBuff);        }    else if (numOfBytes < rBuff->buffRead->dataLen)        {        rBuff->buffRead->dataLen -= numOfBytes;        rBuff->dataRead += numOfBytes;        }    else        {        /* Moving ahead through multiple buffers */        /* Not yet supported */        return(ERROR);        }    rBuff->info.dataContent -= numOfBytes;    /* update info */    rBuff->info.bytesRead += numOfBytes;    rBuff->info.readsSinceReset++;    /* Critical Region End */    return (OK);    }/********************************************************************************* rBuffFlush - Flush data from a ring of buffers** This routine causes any data held in a buffer to be uploaded and is* used to clear data that falls below the specified threshold.** NOMANUAL*/STATUS rBuffFlush    (    BUFFER_ID buffId		/* generic identifier for this buffer */    )    {    RBUFF_ID rBuff;		/* specific identifier for this rBuff */    int result, originalThreshold;    /* Get access to the private members of this particular rBuff. */    rBuff = (RBUFF_ID) buffId;    result = OK;    if (!rBuff->info.dataContent)        {        return(OK);        }    /* Store the original threshold */    originalThreshold = rBuff->info.threshold;    rBuff->info.threshold = 0;    while (rBuff->info.dataContent > 0 && result != ERROR)        {        if (semGive (&rBuff->buffDesc.threshXSem) == OK)            {            /* Cause a reschedule to allow uploader in */            taskDelay(0);            }        else            {            result = ERROR;            }        }    rBuff->info.threshold = originalThreshold;    return(result);}/********************************************************************************* rBuffReset - reset an extendable ring of buffers** This routine resets an already created extendable ring of buffers to its* initial state. This loses any data held in the buffer. Any buffers held* above the specified minimum number are deallocated.** NOMANUAL*/STATUS rBuffReset    (    BUFFER_ID buffId		/* generic identifier for this buffer */    )    {    RBUFF_ID rBuff;		/* specific identifier for this rBuff */    RBUFF_LOCK (rBuff);    /* Get access to the private members of this particular rBuff. */    rBuff = (RBUFF_ID) buffId;    /* Now reset the ring of buffers. */    if (rBuff->info.currBuffs > rBuff->info.minBuffs)        {        UINT32 excessBuffs, count;

⌨️ 快捷键说明

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