diff --git a/kernel/sem.c b/kernel/sem.c index 67116eada84..90876c834a3 100644 --- a/kernel/sem.c +++ b/kernel/sem.c @@ -96,7 +96,7 @@ void z_impl_k_sem_give(struct k_sem *sem) { k_spinlock_key_t key = k_spin_lock(&lock); struct k_thread *thread; - bool resched = true; + bool resched; SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_sem, give, sem); @@ -105,6 +105,7 @@ void z_impl_k_sem_give(struct k_sem *sem) if (unlikely(thread != NULL)) { arch_thread_return_value_set(thread, 0); z_ready_thread(thread); + resched = true; } else { sem->count += (sem->count != sem->limit) ? 1U : 0U; resched = handle_poll_events(sem); @@ -166,12 +167,14 @@ void z_impl_k_sem_reset(struct k_sem *sem) { struct k_thread *thread; k_spinlock_key_t key = k_spin_lock(&lock); + bool resched = false; while (true) { thread = z_unpend_first_thread(&sem->wait_q); if (thread == NULL) { break; } + resched = true; arch_thread_return_value_set(thread, -EAGAIN); z_ready_thread(thread); } @@ -179,9 +182,13 @@ void z_impl_k_sem_reset(struct k_sem *sem) SYS_PORT_TRACING_OBJ_FUNC(k_sem, reset, sem); - (void)handle_poll_events(sem); + resched = handle_poll_events(sem) || resched; - z_reschedule(&lock, key); + if (resched) { + z_reschedule(&lock, key); + } else { + k_spin_unlock(&lock, key); + } } #ifdef CONFIG_USERSPACE