csanikita92 wrote on Sunday, July 08, 2018:
Thanks for the reply. I understood the synchronization mechanisms you explained. But here is a situation I’m still unclear about.
While going through the FreeRTOSv10.0.0 code, I encountered the following two fromISR API functions: xQueueReceiveFromISR and uxQueueMessagesWaitingFromISR, as defined below
BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) //code snippet
{
BaseType_t xReturn;
UBaseType_t uxSavedInterruptStatus;
Queue_t * const pxQueue = ( Queue_t * ) xQueue;
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{
const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting;
if( uxMessagesWaiting > ( UBaseType_t ) 0 )
{
const int8_t cRxLock = pxQueue->cRxLock;
prvCopyDataFromQueue( pxQueue, pvBuffer );
//(PROBLEMATIC ACCESS)
pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1;
//some code here
}
else{
//some code here
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
return xReturn;
}
and
UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) //code snippet
{
UBaseType_t uxReturn;
configASSERT( xQueue );
uxReturn = ( ( Queue_t * ) xQueue )->uxMessagesWaiting; // (PROBLEMATIC ACCESS)
return uxReturn;
}
Now, consider the following application code snippet taken from FreeRTOS/Demo/CORTEX_LPC1768_GCC_Rowley/LPCUSB/ USB_CDC.c :
static void BulkIn(unsigned char bEP, unsigned char bEPStatus)
{
long lHigherPriorityTaskWoken = pdFALSE;
// some code here
if (uxQueueMessagesWaitingFromISR( … ) == 0) { //CALL 1
// some code here
return;
}
if( xQueueReceiveFromISR( … ) //CALL 2
{
break;
}
//some code here
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
Here, suppose 2 tasks are created which call the method BulkIn, then, there can be an instance of uxQueueMessagesWaitingFromISR (Call 1) and xQueueReceiveFromISR (Call 2) running simultaneously. In this case, there is a conflicting access to uxMessagesWaiting.
We realize that xQueueReceiveFromISR calls portSET_INTERRUPT_MASK_FROM_ISR() to prevent interrupt nesting but uxQueueMessagesWaitingFromISR does not. It can happen that while uxQueueMessagesWaitingFromISR is being executed, a call to xQueueReceiveFromISR comes
which results in conflicting simultaneous accesses to uxMessagesWaiting.
Hence, the value of uxMessagesWaiting might become inconsistent.
Please verify whether my observation is correct or not?
Thanks,
Nikita