kernel: k_busy_wait() should return immediately on zero timeout

When CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT is not defined, cycles_to_wait
is calculated using a division operation. This calculation could take a
significant amount of time (a few microseconds on some architectures,
depending on the system clock).
In the special case of zero usec_to_wait, the function should return
immediately rather than spend time on calculations.
For example, in spi driver (spi_context.h, _spi_context_cs_control()),
k_busy_wait() can be called with zero delay. This can increase spi
transaction time significantly.
Another improvement, is moving the start_cycles initialization
before cycles_to_wait calculation, so the time it takes to calculate
cycles_to_wait will be taken into account.

Signed-off-by: David Komel <a8961713@gmail.com>
This commit is contained in:
David Komel 2020-10-13 07:52:01 +03:00 committed by Anas Nashif
commit 211e5b73c0

View file

@ -121,14 +121,19 @@ bool z_is_thread_essential(void)
#ifdef CONFIG_SYS_CLOCK_EXISTS
void z_impl_k_busy_wait(uint32_t usec_to_wait)
{
if (usec_to_wait == 0) {
return;
}
#if !defined(CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT)
uint32_t start_cycles = k_cycle_get_32();
/* use 64-bit math to prevent overflow when multiplying */
uint32_t cycles_to_wait = (uint32_t)(
(uint64_t)usec_to_wait *
(uint64_t)sys_clock_hw_cycles_per_sec() /
(uint64_t)USEC_PER_SEC
);
uint32_t start_cycles = k_cycle_get_32();
for (;;) {
uint32_t current_cycles = k_cycle_get_32();