mirror of
https://github.com/Dasharo/zephyr.git
synced 2026-03-06 14:57:20 -08:00
kernel: fix race conditions with z_ready_thread
Several internal APIs wrote thread attributes (return value, mainly) _after_ calling `z_ready_thread`. This is unsafe, at least in SMP, because another core could have already picked up and run the thread. Fixes #32800. Signed-off-by: James Harris <james.harris@intel.com>
This commit is contained in:
committed by
Anas Nashif
parent
bb014514e0
commit
c7bb423f3e
@@ -64,9 +64,9 @@ int z_impl_k_condvar_broadcast(struct k_condvar *condvar)
|
||||
/* wake up any threads that are waiting to write */
|
||||
while ((pending_thread = z_unpend_first_thread(&condvar->wait_q)) !=
|
||||
NULL) {
|
||||
woken++;
|
||||
arch_thread_return_value_set(pending_thread, 0);
|
||||
z_ready_thread(pending_thread);
|
||||
woken++;
|
||||
}
|
||||
|
||||
z_reschedule(&lock, key);
|
||||
|
||||
@@ -41,9 +41,9 @@ int z_impl_k_futex_wake(struct k_futex *futex, bool wake_all)
|
||||
do {
|
||||
thread = z_unpend_first_thread(&futex_data->wait_q);
|
||||
if (thread) {
|
||||
z_ready_thread(thread);
|
||||
arch_thread_return_value_set(thread, 0);
|
||||
woken++;
|
||||
arch_thread_return_value_set(thread, 0);
|
||||
z_ready_thread(thread);
|
||||
}
|
||||
} while (thread && wake_all);
|
||||
|
||||
|
||||
@@ -108,10 +108,10 @@ int z_impl_k_stack_push(struct k_stack *stack, stack_data_t data)
|
||||
first_pending_thread = z_unpend_first_thread(&stack->wait_q);
|
||||
|
||||
if (first_pending_thread != NULL) {
|
||||
z_ready_thread(first_pending_thread);
|
||||
|
||||
z_thread_return_value_set_with_data(first_pending_thread,
|
||||
0, (void *)data);
|
||||
|
||||
z_ready_thread(first_pending_thread);
|
||||
z_reschedule(&stack->lock, key);
|
||||
goto end;
|
||||
} else {
|
||||
|
||||
@@ -82,9 +82,9 @@ void z_timer_expiration_handler(struct _timeout *t)
|
||||
*/
|
||||
z_unpend_thread_no_timeout(thread);
|
||||
|
||||
z_ready_thread(thread);
|
||||
|
||||
arch_thread_return_value_set(thread, 0);
|
||||
|
||||
z_ready_thread(thread);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -142,8 +142,8 @@ int pthread_mutex_unlock(pthread_mutex_t *m)
|
||||
if (thread) {
|
||||
m->owner = (pthread_t)thread;
|
||||
m->lock_count++;
|
||||
z_ready_thread(thread);
|
||||
arch_thread_return_value_set(thread, 0);
|
||||
z_ready_thread(thread);
|
||||
z_reschedule_irqlock(key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user