-
Notifications
You must be signed in to change notification settings - Fork 2k
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
core/sched.c: fix _runqueue_pop() removing wrong thread #20938
Conversation
static inline clist_node_t *clist_remove(clist_node_t *list, clist_node_t *node)
{
if (list->next) {
if (list->next->next == node) {
return clist_lpop(list);
}
else { So in the common case, this just adds two if conditions. |
If the common case is that there are exactly one or two threads, and we want to remove the first. If there are more, it will start looping from the second. But probably good enough. |
looks like It's probably just a few bytes and |
seems to be working again. |
No, CI still failed |
on my branch:
So a code-size increase by 84 bytes. I suppose this happens because Also, why is All checks have passed active if some build failed? |
With the toolchain used in the CI the binary get's smaller. The increase by 84 B was enough to tip it over the limit, as it is now 8 B larger than flash is available. That is fine. We want things to be correct first and small/efficient second. So just add the board to the list in the |
13d9b9c
to
ba71ba7
Compare
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.