Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task should be not blocked if flag which are we waiting for has been already set #86

Conversation

lkasperowicz
Copy link
Contributor

@lkasperowicz lkasperowicz commented Feb 27, 2024

Without changes:

void TestTask(void *argument)
{
  /* Infinite loop */
  for(;;)
  {
    uint32_t flags = 0;
    osThreadFlagsSet(testTaskHandle, 1<<0);
    flags = osThreadFlagsWait(1<<0, osFlagsWaitAny, osWaitForever );
    osDelay(1);
    osThreadFlagsSet(testTaskHandle, 1<<0);
    osThreadFlagsSet(testTaskHandle, 1<<1);
    flags = osThreadFlagsWait(1<<0, osFlagsWaitAny, osWaitForever );
    osDelay(1);
    flags = osThreadFlagsWait(1<<1, osFlagsWaitAny, osWaitForever ); // task is blocked here even though 1<<1 flag has been 
    // already set
    osDelay(1);
  }
}

To be more consistent in the way of handling Flags (whether Thread Flags or Event Flags is used) osThreadFlagsWait should not block a task when flag which we are waiting for has been already set. For instance, the same code but using Event Flags

void TestTask(void *argument)
{
  osEventFlagsId_t evt_id = osEventFlagsNew(NULL);

  for(;;)
  {
    uint32_t flags = 0;
    osEventFlagsSet(evt_id, 1<<0);
    flags = osEventFlagsWait(evt_id, 1<<0, osFlagsWaitAny, osWaitForever );
    osDelay(1);
    osEventFlagsSet(evt_id, 1<<0);
    osEventFlagsSet(evt_id, 1<<1);
    flags = osEventFlagsWait(evt_id, 1<<0, osFlagsWaitAny, osWaitForever );
    osDelay(1);
    flags = osEventFlagsWait(evt_id, 1<<1, osFlagsWaitAny, osWaitForever ); // task is not blocked, value 2 is returned
    osDelay(1);
  }
}

When osThreadFlagsWait waits only for (1<<0) flag but (1<<1) flag is also set then inside FreeRTOS xTaskNotifyWait function notification state is marked as taskNOT_WAITING_NOTIFICATION.

When next osThreadFlagsWait waits for (1<<1) flag, task goes to BLOCKED state even though (1<<1) flag is actually set and task's notification value is 2 (1<<1) but task's notification state is taskNOT_WAITING_NOTIFICATION.

To resolve this issue task's notification state should be marked as taskNOTIFICATION_RECEIVED again after previous osThreadFlagsWait.

@VladimirUmek
Copy link
Collaborator

Hi Lukasz,

many thanks for your investigation, reproducer and the bugfix implementation! I've checked the behavior and it looks good.
I will perform some additional tests and with a bit of coding style alignment your implementation will be merged!

@VladimirUmek VladimirUmek merged commit bb8a350 into ARM-software:main Mar 8, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants