Skip to content

Commit d0686d5

Browse files
committed
Don't suspend scheduler if task already notified
1 parent d0d55f3 commit d0686d5

File tree

1 file changed

+70
-69
lines changed

1 file changed

+70
-69
lines changed

tasks.c

Lines changed: 70 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -7653,68 +7653,68 @@ TickType_t uxTaskResetEventItemValue( void )
76537653
TickType_t xTicksToWait )
76547654
{
76557655
uint32_t ulReturn;
7656-
BaseType_t xAlreadyYielded, xShouldBlock = pdFALSE;
76577656

76587657
traceENTER_ulTaskGenericNotifyTake( uxIndexToWaitOn, xClearCountOnExit, xTicksToWait );
76597658

76607659
configASSERT( uxIndexToWaitOn < configTASK_NOTIFICATION_ARRAY_ENTRIES );
76617660

7662-
/* We suspend the scheduler here as prvAddCurrentTaskToDelayedList is a
7663-
* non-deterministic operation. */
7664-
vTaskSuspendAll();
7661+
/* If the notification count is zero, and if we are willing to wait for a
7662+
* notification, then block the task and wait. */
7663+
if( ( pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] == 0U ) && ( xTicksToWait > ( TickType_t ) 0 ) )
76657664
{
7666-
/* We MUST enter a critical section to atomically check if a notification
7667-
* has occurred and set the flag to indicate that we are waiting for
7668-
* a notification. If we do not do so, a notification sent from an ISR
7669-
* will get lost. */
7670-
taskENTER_CRITICAL();
7665+
BaseType_t xAlreadyYielded, xShouldBlock = pdFALSE;
7666+
7667+
/* We suspend the scheduler here as prvAddCurrentTaskToDelayedList is a
7668+
* non-deterministic operation. */
7669+
vTaskSuspendAll();
76717670
{
7672-
/* Only block if the notification count is not already non-zero. */
7673-
if( pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] == 0U )
7671+
/* We MUST enter a critical section to atomically check if a notification
7672+
* has occurred and set the flag to indicate that we are waiting for
7673+
* a notification. If we do not do so, a notification sent from an ISR
7674+
* will get lost. */
7675+
taskENTER_CRITICAL();
76747676
{
7675-
/* Mark this task as waiting for a notification. */
7676-
pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskWAITING_NOTIFICATION;
7677-
7678-
if( xTicksToWait > ( TickType_t ) 0 )
7677+
/* Only block if the notification count is not already non-zero. */
7678+
if( pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] == 0U )
76797679
{
7680+
/* Mark this task as waiting for a notification. */
7681+
pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskWAITING_NOTIFICATION;
7682+
7683+
/* Arrange to wait for a notification. */
76807684
xShouldBlock = pdTRUE;
76817685
}
76827686
else
76837687
{
76847688
mtCOVERAGE_TEST_MARKER();
76857689
}
76867690
}
7691+
taskEXIT_CRITICAL();
7692+
7693+
/* We are now out of the critical section but the scheduler is still
7694+
* suspended, so we are safe to do non-deterministic operations such
7695+
* as prvAddCurrentTaskToDelayedList. */
7696+
if( xShouldBlock == pdTRUE )
7697+
{
7698+
traceTASK_NOTIFY_TAKE_BLOCK( uxIndexToWaitOn );
7699+
prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE );
7700+
}
76877701
else
76887702
{
76897703
mtCOVERAGE_TEST_MARKER();
76907704
}
76917705
}
7692-
taskEXIT_CRITICAL();
7706+
xAlreadyYielded = xTaskResumeAll();
76937707

7694-
/* We are now out of the critical section but the scheduler is still
7695-
* suspended, so we are safe to do non-deterministic operations such
7696-
* as prvAddCurrentTaskToDelayedList. */
7697-
if( xShouldBlock == pdTRUE )
7708+
/* Force a reschedule if xTaskResumeAll has not already done so. */
7709+
if( ( xShouldBlock == pdTRUE ) && ( xAlreadyYielded == pdFALSE ) )
76987710
{
7699-
traceTASK_NOTIFY_TAKE_BLOCK( uxIndexToWaitOn );
7700-
prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE );
7711+
taskYIELD_WITHIN_API();
77017712
}
77027713
else
77037714
{
77047715
mtCOVERAGE_TEST_MARKER();
77057716
}
77067717
}
7707-
xAlreadyYielded = xTaskResumeAll();
7708-
7709-
/* Force a reschedule if xTaskResumeAll has not already done so. */
7710-
if( ( xShouldBlock == pdTRUE ) && ( xAlreadyYielded == pdFALSE ) )
7711-
{
7712-
taskYIELD_WITHIN_API();
7713-
}
7714-
else
7715-
{
7716-
mtCOVERAGE_TEST_MARKER();
7717-
}
77187718

77197719
taskENTER_CRITICAL();
77207720
{
@@ -7757,72 +7757,73 @@ TickType_t uxTaskResetEventItemValue( void )
77577757
uint32_t * pulNotificationValue,
77587758
TickType_t xTicksToWait )
77597759
{
7760-
BaseType_t xReturn, xAlreadyYielded, xShouldBlock = pdFALSE;
7760+
BaseType_t xReturn;
77617761

77627762
traceENTER_xTaskGenericNotifyWait( uxIndexToWaitOn, ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait );
77637763

77647764
configASSERT( uxIndexToWaitOn < configTASK_NOTIFICATION_ARRAY_ENTRIES );
77657765

7766-
/* We suspend the scheduler here as prvAddCurrentTaskToDelayedList is a
7767-
* non-deterministic operation. */
7768-
vTaskSuspendAll();
7766+
/* If the task hasn't received a notification, and if we are willing to wait
7767+
* for it, then block the task and wait. */
7768+
if( ( pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] != taskNOTIFICATION_RECEIVED ) && ( xTicksToWait > ( TickType_t ) 0 ) )
77697769
{
7770-
/* We MUST enter a critical section to atomically check and update the
7771-
* task notification value. If we do not do so, a notification from
7772-
* an ISR will get lost. */
7773-
taskENTER_CRITICAL();
7770+
BaseType_t xAlreadyYielded, xShouldBlock = pdFALSE;
7771+
7772+
/* We suspend the scheduler here as prvAddCurrentTaskToDelayedList is a
7773+
* non-deterministic operation. */
7774+
vTaskSuspendAll();
77747775
{
7775-
/* Only block if a notification is not already pending. */
7776-
if( pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] != taskNOTIFICATION_RECEIVED )
7776+
/* We MUST enter a critical section to atomically check and update the
7777+
* task notification value. If we do not do so, a notification from
7778+
* an ISR will get lost. */
7779+
taskENTER_CRITICAL();
77777780
{
7778-
/* Clear bits in the task's notification value as bits may get
7779-
* set by the notifying task or interrupt. This can be used
7780-
* to clear the value to zero. */
7781-
pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] &= ~ulBitsToClearOnEntry;
7781+
/* Only block if a notification is not already pending. */
7782+
if( pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] != taskNOTIFICATION_RECEIVED )
7783+
{
7784+
/* Clear bits in the task's notification value as bits may get
7785+
* set by the notifying task or interrupt. This can be used
7786+
* to clear the value to zero. */
7787+
pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] &= ~ulBitsToClearOnEntry;
77827788

7783-
/* Mark this task as waiting for a notification. */
7784-
pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskWAITING_NOTIFICATION;
7789+
/* Mark this task as waiting for a notification. */
7790+
pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskWAITING_NOTIFICATION;
77857791

7786-
if( xTicksToWait > ( TickType_t ) 0 )
7787-
{
7792+
/* Arrange to wait for a notification. */
77887793
xShouldBlock = pdTRUE;
77897794
}
77907795
else
77917796
{
77927797
mtCOVERAGE_TEST_MARKER();
77937798
}
77947799
}
7800+
taskEXIT_CRITICAL();
7801+
7802+
/* We are now out of the critical section but the scheduler is still
7803+
* suspended, so we are safe to do non-deterministic operations such
7804+
* as prvAddCurrentTaskToDelayedList. */
7805+
if( xShouldBlock == pdTRUE )
7806+
{
7807+
traceTASK_NOTIFY_WAIT_BLOCK( uxIndexToWaitOn );
7808+
prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE );
7809+
}
77957810
else
77967811
{
77977812
mtCOVERAGE_TEST_MARKER();
77987813
}
77997814
}
7800-
taskEXIT_CRITICAL();
7815+
xAlreadyYielded = xTaskResumeAll();
78017816

7802-
/* We are now out of the critical section but the scheduler is still
7803-
* suspended, so we are safe to do non-deterministic operations such
7804-
* as prvAddCurrentTaskToDelayedList. */
7805-
if( xShouldBlock == pdTRUE )
7817+
/* Force a reschedule if xTaskResumeAll has not already done so. */
7818+
if( ( xShouldBlock == pdTRUE ) && ( xAlreadyYielded == pdFALSE ) )
78067819
{
7807-
traceTASK_NOTIFY_WAIT_BLOCK( uxIndexToWaitOn );
7808-
prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE );
7820+
taskYIELD_WITHIN_API();
78097821
}
78107822
else
78117823
{
78127824
mtCOVERAGE_TEST_MARKER();
78137825
}
78147826
}
7815-
xAlreadyYielded = xTaskResumeAll();
7816-
7817-
/* Force a reschedule if xTaskResumeAll has not already done so. */
7818-
if( ( xShouldBlock == pdTRUE ) && ( xAlreadyYielded == pdFALSE ) )
7819-
{
7820-
taskYIELD_WITHIN_API();
7821-
}
7822-
else
7823-
{
7824-
mtCOVERAGE_TEST_MARKER();
7825-
}
78267827

78277828
taskENTER_CRITICAL();
78287829
{

0 commit comments

Comments
 (0)