core/sched.c: fix _runqueue_pop() removing wrong thread #20938
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Contribution description
_runqueue_pop()
callsclist_lpop()
, which pops the leftmost entry in the thread's priority runqueue, but not necessarily the one passed as argument.I understand the original logic behind this: if a thread is to be removed, then it is so because it is about to block on something or exit. And a thread can only block or exit if it's currently running. As a result, it must be the leftmost entry on the runqueue. But this isn't always true. Consider
sched_change_priority()
, which does the following:thread_is_active()
returns true if a thread is either running or queued to be running. So the_runqueue_pop()
might retrieve any thread. Let's extend_runqueue_pop()
with the following assertion:Running this will trigger the assertion:
If we change
_runqueue_pop()
to search for the specific thread:Then everything is all right.
The only ugly thing is that, when the thread is indeed running (vast majority of cases), due to how
clist
s are implemented the whole list is walked to remove the thread.Testing procedure
I briefly tested this code on a SAM0 board.