in stream_buffer.c [542:670]
size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
const void * pvTxData,
size_t xDataLengthBytes,
TickType_t xTicksToWait )
{
StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
size_t xReturn, xSpace = 0;
size_t xRequiredSpace = xDataLengthBytes;
TimeOut_t xTimeOut;
size_t xMaxReportedSpace = 0;
configASSERT( pvTxData );
configASSERT( pxStreamBuffer );
/* The maximum amount of space a stream buffer will ever report is its length
* minus 1. */
xMaxReportedSpace = pxStreamBuffer->xLength - ( size_t ) 1;
/* This send function is used to write to both message buffers and stream
* buffers. If this is a message buffer then the space needed must be
* increased by the amount of bytes needed to store the length of the
* message. */
if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
{
xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH;
/* Overflow? */
configASSERT( xRequiredSpace > xDataLengthBytes );
/* If this is a message buffer then it must be possible to write the
* whole message. */
if( xRequiredSpace > xMaxReportedSpace )
{
/* The message would not fit even if the entire buffer was empty,
* so don't wait for space. */
xTicksToWait = ( TickType_t ) 0;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
/* If this is a stream buffer then it is acceptable to write only part
* of the message to the buffer. Cap the length to the total length of
* the buffer. */
if( xRequiredSpace > xMaxReportedSpace )
{
xRequiredSpace = xMaxReportedSpace;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
if( xTicksToWait != ( TickType_t ) 0 )
{
vTaskSetTimeOutState( &xTimeOut );
do
{
/* Wait until the required number of bytes are free in the message
* buffer. */
taskENTER_CRITICAL();
{
xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
if( xSpace < xRequiredSpace )
{
/* Clear notification state as going to wait for space. */
( void ) xTaskNotifyStateClear( NULL );
/* Should only be one writer. */
configASSERT( pxStreamBuffer->xTaskWaitingToSend == NULL );
pxStreamBuffer->xTaskWaitingToSend = xTaskGetCurrentTaskHandle();
}
else
{
taskEXIT_CRITICAL();
break;
}
}
taskEXIT_CRITICAL();
traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer );
( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );
pxStreamBuffer->xTaskWaitingToSend = NULL;
} while( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
if( xSpace == ( size_t ) 0 )
{
xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace );
if( xReturn > ( size_t ) 0 )
{
traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn );
/* Was a task waiting for the data? */
if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )
{
sbSEND_COMPLETED( pxStreamBuffer );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer );
}
return xReturn;
}