You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(task): handle the case where next_running_task == prev_running_task in choose_next_running_task
Fixes the test case `timer_zero_period` failing on `gr_peach`.
The following diagram illustrates a simplified execution flow that
causes this bug:
wait_until_woken_up:
[running_task = &task1]
task1.state = Waiting
leave_cpu_lock()
interrupt_handler:
make_ready(&task1):
task1.state = Ready
queue.push_back(&task1)
yield_cpu()
choose_next_running_task():
next_running_task = queue.pop_front()
[next_running_task = &task1]
next_running_task.state = Running
make_ready(&running_task):
running_task.state = Ready
queue.push_back(&running_task)
running_task = next_running_task
yield_cpu()
[task1.state = Ready]
yield_cpu()
[task1.state = Ready]
<loop indefinitely>
(Conditional branches are omitted. Brackets [] denotes excerpts of
current internal states that destine the outcomes of conditional
branches.)
`choose_next_running_task` did not handle the case where
`next_running_task == prev_running_task`. As a result, it transitioned
`next_running_task` into Ready state when it's expected to transition it
into Running state.
The correct execution flow looks like the following:
wait_until_woken_up:
[running_task = &task1]
task1.state = Waiting
leave_cpu_lock()
interrupt_handler:
make_ready(&task1):
task1.state = Ready
queue.push_back(&task1)
yield_cpu()
choose_next_running_task():
next_running_task = queue.pop_front()
[next_running_task = &task1]
next_running_task.state = Running
[next_running_task = running_task]
yield_cpu()
[task1.state = Running]
enter_cpu_lock()
0 commit comments