Hello,
I believe I have found a possible race condition in experimental_task_manager / task_manager.c, task_events_wait().
The race occurs if a task calls task_events_wait(), while an interrupt calls task_events_set(), for the same event; the event is ignored and the waiting task waits indefinitely.
The problem appears fixed if I add 4 lines to task_events_wait(), indicated by the comments below:
uint32_t task_events_wait(uint32_t evt_mask)
{
uint32_t current_events;
ASSERT((evt_mask & ~TASK_FLAG_SIGNAL_MASK) == 0);
for (;;)
{
current_events = s_task_state[s_current_task_id].flags & evt_mask;
if (current_events != 0)
{
(void)nrf_atomic_u32_and(&s_task_state[s_current_task_id].flags, ~current_events);
break;
}
TASK_STATE_SUSPENDED(s_current_task_id);
// Race condition fix starts ----------------------------------------
if (current_events != (s_task_state[s_current_task_id].flags & evt_mask))
{
continue;
}
// Race condition fix ends ------------------------------------------
task_yield();
}
return current_events;
}
Appreciate if you could please confirm if this is indeed a race condition, and if this fix is appropriate.
Thanks!