kernel: Clamp k_sleep() return value on overflow
k_sleep() returns a 32 bit count of milliseconds, as that was its historical API. But it now accepts a potentially 64 bit tick count as an argument, leading to situations where an early wakeup will produce sleep times that aren't representable. Clamp this instead of truncating to an arbitrary value. Naive code will likely do the right thing with the large return (just sleeping an extra round), and sophisticated apps can detect INT_MAX to enable more elaborate retry logic. (Also fixes a somewhat unfortunate puncutation error in the docs that implied that it returns zero on early wakeup!) Fixes: #84669 Signed-off-by: Andy Ross <andyross@google.com>
This commit is contained in:
parent
57e8d5ecfb
commit
8b4ed6655a
2 changed files with 9 additions and 8 deletions
|
@ -545,9 +545,10 @@ __syscall int k_thread_join(struct k_thread *thread, k_timeout_t timeout);
|
|||
*
|
||||
* @param timeout Desired duration of sleep.
|
||||
*
|
||||
* @return Zero if the requested time has elapsed or if the thread was woken up
|
||||
* by the \ref k_wakeup call, the time left to sleep rounded up to the nearest
|
||||
* millisecond.
|
||||
* @return Zero if the requested time has elapsed or the time left to
|
||||
* sleep rounded up to the nearest millisecond (e.g. if the thread was
|
||||
* awoken by the \ref k_wakeup call). Will be clamped to INT_MAX in
|
||||
* the case where the remaining time is unrepresentable in an int32_t.
|
||||
*/
|
||||
__syscall int32_t k_sleep(k_timeout_t timeout);
|
||||
|
||||
|
|
|
@ -1123,12 +1123,12 @@ int32_t z_impl_k_sleep(k_timeout_t timeout)
|
|||
|
||||
ticks = z_tick_sleep(ticks);
|
||||
|
||||
int32_t ret = K_TIMEOUT_EQ(timeout, K_FOREVER) ? K_TICKS_FOREVER :
|
||||
k_ticks_to_ms_ceil64(ticks);
|
||||
/* k_sleep() still returns 32 bit milliseconds for compatibility */
|
||||
int64_t ms = K_TIMEOUT_EQ(timeout, K_FOREVER) ? K_TICKS_FOREVER :
|
||||
CLAMP(k_ticks_to_ms_ceil64(ticks), 0, INT_MAX);
|
||||
|
||||
SYS_PORT_TRACING_FUNC_EXIT(k_thread, sleep, timeout, ret);
|
||||
|
||||
return ret;
|
||||
SYS_PORT_TRACING_FUNC_EXIT(k_thread, sleep, timeout, ms);
|
||||
return (int32_t) ms;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue