Skip to content

Commit

Permalink
kernel/thread: Cancel timeouts on k_thread_suspend(), make schedule p…
Browse files Browse the repository at this point in the history
…oint

When suspending a thread, cancel any pending timeouts which might wake
it up unexpectedly.  Also, make suspending the current thread
(specifically) a schedule point, as callers are clearly going to
expect that to be synchronous.

Also fix a documentation weirdness.  The phrasing in the earlier docs
for k_thread_suspend() was confusing: it could be interpreted as
either document the current (essentially buggy) behavior that threads
will "wake up" due to preexisting timeouts, OR to mean that thread
timeouts will continue to be tracked so that resuming a thread that
was sleeping will continue to sleep until the timeout (something that
has never been implemented: k_sleep() is implemented on top of
suspend).  Rewrite to document what we actually implement.

Fixes zephyrproject-rtos#20033

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
  • Loading branch information
Andy Ross authored and jaizpuruzin committed Nov 24, 2023
1 parent 191dc91 commit 6475034
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 4 deletions.
11 changes: 7 additions & 4 deletions include/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -1140,10 +1140,13 @@ int k_thread_cpu_mask_disable(k_tid_t thread, int cpu);
/**
* @brief Suspend a thread.
*
* This routine prevents the kernel scheduler from making @a thread the
* current thread. All other internal operations on @a thread are still
* performed; for example, any timeout it is waiting on keeps ticking,
* kernel objects it is waiting on are still handed to it, etc.
* This routine prevents the kernel scheduler from making @a thread
* the current thread. All other internal operations on @a thread are
* still performed; for example, kernel objects it is waiting on are
* still handed to it. Note that any existing timeouts
* (e.g. k_sleep(), or a timeout argument to k_sem_take() et. al.)
* will be canceled. On resume, the thread will begin running
* immediately and return from the blocked call.
*
* If @a thread is already suspended, the routine has no effect.
*
Expand Down
6 changes: 6 additions & 0 deletions kernel/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,13 @@ void z_thread_single_suspend(struct k_thread *thread)
z_remove_thread_from_ready_q(thread);
}

(void)z_abort_thread_timeout(thread);

z_mark_thread_as_suspended(thread);

if (thread == _current) {
z_reschedule_unlocked();
}
}

void z_impl_k_thread_suspend(struct k_thread *thread)
Expand Down

0 comments on commit 6475034

Please sign in to comment.