-
Notifications
You must be signed in to change notification settings - Fork 2.1k
core/thread_flags_group: use portable implementation #21895
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
base: master
Are you sure you want to change the base?
Conversation
|
@derMihai: Would you mind to also take a look? |
8c63a9b to
150db5b
Compare
|
Is this a 2 ACK kind of PR? |
I'd say so, as it touches |
| } | ||
|
|
||
| irq_restore(irq_state); | ||
| if (yield) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't this be called unconditionally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it will be faster in case all threads of the group either where already pending or not currently actively waiting for one of the flags in mask.
|
Huh, I thought this was sorted out: #21123 (comment) But if not, then you're totally right and this PR looks fine. |
|
I would assume that @kaspar030 was referring to the crash with "sorted out". And indeed, that crash did not happen anymore. Just sending out PendSV (or similar) in We certainly cannot assume that each and every architecture has a software IRQ usable for context switching without limiting portability. |
d705c34 to
aa010b8
Compare
mguetschow
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for finding and fixing!
There is quite a lot of code that is just needed for debugging, but which makes the function look more complex than it is. I don't have a good suggestion how, but maybe you have an idea how to leave it more concise?
All uses of thread_flags_wake() also had to set the flags anyway, so we can just combine those operations into a new thread_flags_set_internal() and update the users to use that instead.
The previous implementation relied on `thread_flag_set()` to defer the context switch when called with IRQs disabled until `irq_restore()` is called. This however can only be the case when `thread_yield_higher` triggers an IRQ and performs the context switch within the ISR. This allowed the previous implementation to continue calling `thread_flag_set()` for the remaining group members. This however is an implementation detail that is not part of the API contract. Platforms that do not have a service request IRQ may have to use other means for context switching that do not get deferred until an `irq_restore()` is called. In that case, the first call to `thread_flags_set()` even with IRQs disabled may directly trigger a context switch to the unblocked thread, even if other group members would also be unblocked and have a higher priority. This changes the implementation to manually set the flags and update the thread status without yielding and keep track whether any thread has been awoken. Only once the states of all threads have been updated, the adapted implementation will now call `thread_yield()` (unless no thread was awoken).
e6c7979 to
d873852
Compare
| bool thread_flags_set_internal(thread_t *thread, thread_flags_t mask) | ||
| { | ||
| thread->flags |= mask; | ||
| return _thread_flags_wake(thread); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that's a nice solution, thanks! Maybe remove thread_flags_wake though - it's not exposed through the header file anymore anyways.
Lines 56 to 59 in a23948c
| int thread_flags_wake(thread_t *thread) | |
| { | |
| return _thread_flags_wake(thread); | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That function has multiple callers...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_thread_flags_wake still has, but thread_flags_wake does not, does it? At least its not exposed through the headerfile anymore and all calls inside thread_flags.c should use the static (_-prefixed) function anyways?
So I'd say thread_flags_wake should be dead code as it stands now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, OK. I could have sworn I dropped it. Maybe reordering the commits didn't work as expected
Contribution description
The previous implementation relied on
thread_flag_set()to defer the context switch when called with IRQs disabled untilirq_restore()is called. This however can only be the case whenthread_yield_highertriggers an IRQ and performs the context switch within the ISR. This allowed the previous implementation to continue callingthread_flag_set()for the remaining group members.This however is an implementation detail that is not part of the API contract. Platforms that do not have a service request IRQ may have to use other means for context switching that do not get deferred until an
irq_restore()is called. In that case, the first call tothread_flags_set()even with IRQs disabled may directly trigger a context switch to the unblocked thread, even if other group members would also be unblocked and have a higher priority.This changes the implementation to manually set the flags and update the thread status without yielding and keep track whether any thread has been awoken. Only once the states of all threads have been updated, the adapted implementation will now call
thread_yield()(unless no thread was awoken).Testing procedure
In
masterIn this PR
Issues/PRs references
None