Skip to content

Commit a651081

Browse files
stream_buffer: require batching buffers to exceed trigger level
Batching stream buffers are documented to unblock receivers only after the buffered byte count exceeds the trigger level, but both xStreamBufferSend() paths currently notify as soon as the count reaches it. That equality case wakes the blocked receiver too early, causing xStreamBufferReceive() to return 0 bytes while the buffer still holds exactly trigger-level data. Route both task and ISR send paths through a shared trigger helper so batching buffers require a strict greater-than check while existing stream and message buffer semantics remain unchanged. Fixes #1375 Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
1 parent 129b09f commit a651081

1 file changed

Lines changed: 40 additions & 2 deletions

File tree

stream_buffer.c

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,15 @@ typedef struct StreamBufferDef_t
256256
*/
257257
static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) PRIVILEGED_FUNCTION;
258258

259+
/*
260+
* Returns pdTRUE when the amount of buffered data should unblock a task that
261+
* is waiting to receive data. Stream batching buffers require the buffered
262+
* data to exceed the trigger level, whereas stream and message buffers unblock
263+
* when the trigger level is reached.
264+
*/
265+
static BaseType_t prvBytesInBufferMeetTriggerLevel( const StreamBuffer_t * const pxStreamBuffer,
266+
size_t xBytesInBuffer ) PRIVILEGED_FUNCTION;
267+
259268
/*
260269
* Add xCount bytes from pucData into the pxStreamBuffer's data storage area.
261270
* This function does not update the buffer's xHead pointer, so multiple writes
@@ -919,7 +928,7 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
919928
traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn );
920929

921930
/* Was a task waiting for the data? */
922-
if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )
931+
if( prvBytesInBufferMeetTriggerLevel( pxStreamBuffer, prvBytesInBuffer( pxStreamBuffer ) ) != pdFALSE )
923932
{
924933
prvSEND_COMPLETED( pxStreamBuffer );
925934
}
@@ -976,7 +985,7 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
976985
if( xReturn > ( size_t ) 0 )
977986
{
978987
/* Was a task waiting for the data? */
979-
if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )
988+
if( prvBytesInBufferMeetTriggerLevel( pxStreamBuffer, prvBytesInBuffer( pxStreamBuffer ) ) != pdFALSE )
980989
{
981990
/* MISRA Ref 4.7.1 [Return value shall be checked] */
982991
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */
@@ -1587,6 +1596,35 @@ static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer )
15871596
}
15881597
/*-----------------------------------------------------------*/
15891598

1599+
static BaseType_t prvBytesInBufferMeetTriggerLevel( const StreamBuffer_t * const pxStreamBuffer,
1600+
size_t xBytesInBuffer )
1601+
{
1602+
BaseType_t xReturn = pdFALSE;
1603+
1604+
if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_BATCHING_BUFFER ) != ( uint8_t ) 0 )
1605+
{
1606+
if( xBytesInBuffer > pxStreamBuffer->xTriggerLevelBytes )
1607+
{
1608+
xReturn = pdTRUE;
1609+
}
1610+
else
1611+
{
1612+
mtCOVERAGE_TEST_MARKER();
1613+
}
1614+
}
1615+
else if( xBytesInBuffer >= pxStreamBuffer->xTriggerLevelBytes )
1616+
{
1617+
xReturn = pdTRUE;
1618+
}
1619+
else
1620+
{
1621+
mtCOVERAGE_TEST_MARKER();
1622+
}
1623+
1624+
return xReturn;
1625+
}
1626+
/*-----------------------------------------------------------*/
1627+
15901628
static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
15911629
uint8_t * const pucBuffer,
15921630
size_t xBufferSizeBytes,

0 commit comments

Comments
 (0)