Add IRQ safe API for message buffer reset (#1033)

* Add API xStreamBufferResetFromISR

Allow reseting the stream buffer from ISR context

Signed-off-by: hagai.moshe <hagaimoshe@outlook.com>
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: hagai.moshe <hagai.moshe@tandemg.com>
Co-authored-by: Rahul Kar <118818625+kar-rahul-aws@users.noreply.github.com>
Co-authored-by: kar-rahul-aws <karahulx@amazon.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h
index 6961184..662c5ea 100644
--- a/include/FreeRTOS.h
+++ b/include/FreeRTOS.h
@@ -1001,6 +1001,10 @@
     #define traceSTREAM_BUFFER_RESET( xStreamBuffer )
 #endif
 
+#ifndef traceSTREAM_BUFFER_RESET_FROM_ISR
+    #define traceSTREAM_BUFFER_RESET_FROM_ISR( xStreamBuffer )
+#endif
+
 #ifndef traceBLOCKING_ON_STREAM_BUFFER_SEND
     #define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer )
 #endif
@@ -2437,6 +2441,14 @@
     #define traceRETURN_xStreamBufferReset( xReturn )
 #endif
 
+#ifndef traceENTER_xStreamBufferResetFromISR
+    #define traceENTER_xStreamBufferResetFromISR( xStreamBuffer )
+#endif
+
+#ifndef traceRETURN_xStreamBufferResetFromISR
+    #define traceRETURN_xStreamBufferResetFromISR( xReturn )
+#endif
+
 #ifndef traceENTER_xStreamBufferSetTriggerLevel
     #define traceENTER_xStreamBufferSetTriggerLevel( xStreamBuffer, xTriggerLevel )
 #endif
diff --git a/include/message_buffer.h b/include/message_buffer.h
index 1b1356c..b58f33f 100644
--- a/include/message_buffer.h
+++ b/include/message_buffer.h
@@ -768,6 +768,10 @@
  *
  * A message buffer can only be reset if there are no tasks blocked on it.
  *
+ * Use xMessageBufferReset() to reset a message buffer from a task.
+ * Use xMessageBufferResetFromISR() to reset a message buffer from an
+ * interrupt service routine (ISR).
+ *
  * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
  * xMessageBufferReset() to be available.
  *
@@ -788,6 +792,38 @@
 /**
  * message_buffer.h
  * @code{c}
+ * BaseType_t xMessageBufferResetFromISR( MessageBufferHandle_t xMessageBuffer );
+ * @endcode
+ *
+ * An interrupt safe version of the API function that resets the message buffer.
+ * Resets a message buffer to its initial empty state, discarding any message it
+ * contained.
+ *
+ * A message buffer can only be reset if there are no tasks blocked on it.
+ *
+ * Use xMessageBufferReset() to reset a message buffer from a task.
+ * Use xMessageBufferResetFromISR() to reset a message buffer from an
+ * interrupt service routine (ISR).
+ *
+ * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
+ * xMessageBufferResetFromISR() to be available.
+ *
+ * @param xMessageBuffer The handle of the message buffer being reset.
+ *
+ * @return If the message buffer was reset then pdPASS is returned.  If the
+ * message buffer could not be reset because either there was a task blocked on
+ * the message queue to wait for space to become available, or to wait for a
+ * a message to be available, then pdFAIL is returned.
+ *
+ * \defgroup xMessageBufferResetFromISR xMessageBufferResetFromISR
+ * \ingroup MessageBufferManagement
+ */
+#define xMessageBufferResetFromISR( xMessageBuffer ) \
+    xStreamBufferResetFromISR( xMessageBuffer )
+
+/**
+ * message_buffer.h
+ * @code{c}
  * size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer );
  * @endcode
  * Returns the number of bytes of free space in the message buffer.
diff --git a/include/stream_buffer.h b/include/stream_buffer.h
index 94a0e0c..dca9851 100644
--- a/include/stream_buffer.h
+++ b/include/stream_buffer.h
@@ -767,6 +767,10 @@
  * are no tasks blocked waiting to either send to or receive from the stream
  * buffer.
  *
+ * Use xStreamBufferReset() to reset a stream buffer from a task.
+ * Use xStreamBufferResetFromISR() to reset a stream buffer from an
+ * interrupt service routine (ISR).
+ *
  * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
  * xStreamBufferReset() to be available.
  *
@@ -785,6 +789,38 @@
  * stream_buffer.h
  *
  * @code{c}
+ * BaseType_t xStreamBufferResetFromISR( StreamBufferHandle_t xStreamBuffer );
+ * @endcode
+ *
+ * An interrupt safe version of the API function that resets the stream buffer.
+ *
+ * Resets a stream buffer to its initial, empty, state.  Any data that was in
+ * the stream buffer is discarded.  A stream buffer can only be reset if there
+ * are no tasks blocked waiting to either send to or receive from the stream
+ * buffer.
+ *
+ * Use xStreamBufferReset() to reset a stream buffer from a task.
+ * Use xStreamBufferResetFromISR() to reset a stream buffer from an
+ * interrupt service routine (ISR).
+ *
+ * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
+ * xStreamBufferResetFromISR() to be available.
+ *
+ * @param xStreamBuffer The handle of the stream buffer being reset.
+ *
+ * @return If the stream buffer is reset then pdPASS is returned.  If there was
+ * a task blocked waiting to send to or read from the stream buffer then the
+ * stream buffer is not reset and pdFAIL is returned.
+ *
+ * \defgroup xStreamBufferResetFromISR xStreamBufferResetFromISR
+ * \ingroup StreamBufferManagement
+ */
+BaseType_t xStreamBufferResetFromISR( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
+
+/**
+ * stream_buffer.h
+ *
+ * @code{c}
  * size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
  * @endcode
  *
diff --git a/stream_buffer.c b/stream_buffer.c
index 44354fb..17a898d 100644
--- a/stream_buffer.c
+++ b/stream_buffer.c
@@ -639,6 +639,68 @@
 }
 /*-----------------------------------------------------------*/
 
+BaseType_t xStreamBufferResetFromISR( StreamBufferHandle_t xStreamBuffer )
+{
+    StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
+    BaseType_t xReturn = pdFAIL;
+    StreamBufferCallbackFunction_t pxSendCallback = NULL, pxReceiveCallback = NULL;
+    UBaseType_t uxSavedInterruptStatus;
+
+    #if ( configUSE_TRACE_FACILITY == 1 )
+        UBaseType_t uxStreamBufferNumber;
+    #endif
+
+    traceENTER_xStreamBufferResetFromISR( xStreamBuffer );
+
+    configASSERT( pxStreamBuffer );
+
+    #if ( configUSE_TRACE_FACILITY == 1 )
+    {
+        /* Store the stream buffer number so it can be restored after the
+         * reset. */
+        uxStreamBufferNumber = pxStreamBuffer->uxStreamBufferNumber;
+    }
+    #endif
+
+    /* Can only reset a message buffer if there are no tasks blocked on it. */
+    uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();
+    {
+        if( ( pxStreamBuffer->xTaskWaitingToReceive == NULL ) && ( pxStreamBuffer->xTaskWaitingToSend == NULL ) )
+        {
+            #if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
+            {
+                pxSendCallback = pxStreamBuffer->pxSendCompletedCallback;
+                pxReceiveCallback = pxStreamBuffer->pxReceiveCompletedCallback;
+            }
+            #endif
+
+            prvInitialiseNewStreamBuffer( pxStreamBuffer,
+                                          pxStreamBuffer->pucBuffer,
+                                          pxStreamBuffer->xLength,
+                                          pxStreamBuffer->xTriggerLevelBytes,
+                                          pxStreamBuffer->ucFlags,
+                                          pxSendCallback,
+                                          pxReceiveCallback );
+
+            #if ( configUSE_TRACE_FACILITY == 1 )
+            {
+                pxStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber;
+            }
+            #endif
+
+            traceSTREAM_BUFFER_RESET_FROM_ISR( xStreamBuffer );
+
+            xReturn = pdPASS;
+        }
+    }
+    taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );
+
+    traceRETURN_xStreamBufferResetFromISR( xReturn );
+
+    return xReturn;
+}
+/*-----------------------------------------------------------*/
+
 BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
                                          size_t xTriggerLevel )
 {