-
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,27 +18,58 @@ | |
| * @} | ||
| */ | ||
|
|
||
| #include <stdbool.h> | ||
|
|
||
| #include "bitarithm.h" | ||
| #include "irq.h" | ||
| #include "thread.h" | ||
| #include "thread_flags_group.h" | ||
|
|
||
| #define ENABLE_DEBUG 0 | ||
| #include "debug.h" | ||
|
|
||
| void thread_flags_group_set(thread_flags_group_t *group, thread_flags_t mask) | ||
| { | ||
| /* Interrupts must be disabled because the threads are not ordered by | ||
| * priority. */ | ||
| unsigned irq_state = irq_disable(); | ||
|
|
||
| DEBUG("thread_flags_group_set(%p, %x):\n", (void *)group, (unsigned)mask); | ||
| DEBUG("| TID | Flags | Status (old) | Status (new) |\n"); | ||
|
|
||
| bool yield = false; | ||
| for (kernel_pid_t i = 0; i < (kernel_pid_t)ARRAY_SIZE(group->members); i++) { | ||
| unsigned pid_block = group->members[i]; | ||
| kernel_pid_t const pid_base = i * UINT_WIDTH; | ||
| uint8_t pid_offs = 0; | ||
|
|
||
| while (pid_block) { | ||
| pid_block = bitarithm_test_and_clear(pid_block, &pid_offs); | ||
| thread_flags_set(thread_get(pid_base + pid_offs), mask); | ||
| kernel_pid_t target_pid = pid_base + pid_offs; | ||
| thread_t *target = thread_get(target_pid); | ||
| if (!target) { | ||
| DEBUG("| %02u | n/a | n/a (dead) | n/a (dead) |\n", | ||
| target_pid); | ||
| continue; | ||
| } | ||
| thread_status_t old_status = target->status; | ||
| bool awoken = thread_flags_set_internal(target, mask); | ||
| thread_status_t new_status = target->status; | ||
| /* NOTE: wait_data is shared by thread_flags with other | ||
| * mechanisms and may e.g. be a pointer to an `msg_t`. | ||
| * Some interpretation of the output is needed by the | ||
| * user of the debug output. */ | ||
| thread_flags_t wait_data = (uint16_t)(uintptr_t)target->wait_data; | ||
mguetschow marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| DEBUG("| %02u | %04x | %12s | %12s |\n", | ||
| (unsigned)target_pid, (unsigned)wait_data, | ||
| thread_state_to_string(old_status), | ||
| thread_state_to_string(new_status)); | ||
| yield = yield || awoken; | ||
| } | ||
| } | ||
|
|
||
| irq_restore(irq_state); | ||
| if (yield) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can't this be called unconditionally?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| thread_yield_higher(); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.