kernel: crude k_busy_wait() implementation

This allows for builds with CONFIG_SYS_CLOCK_EXISTS=n in which case
busy waits are achieved with a crude CPU loop. If ever accuracy is
needed even with such a configuration then implementing arch_busy_wait()
should be considered.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This commit is contained in:
Nicolas Pitre 2023-07-19 14:45:19 -04:00 committed by Anas Nashif
commit 13a6c45452
2 changed files with 24 additions and 1 deletions

View file

@ -755,6 +755,18 @@ config SYS_CLOCK_MAX_TIMEOUT_DAYS
algorithm is selected for conversion if maximum timeout represented in
source frequency domain multiplied by target frequency fits in 64 bits.
config BUSYWAIT_CPU_LOOPS_PER_USEC
int "Number of CPU loops per microsecond for crude busy looping"
depends on !SYS_CLOCK_EXISTS && !ARCH_HAS_CUSTOM_BUSY_WAIT
default 500
help
Calibration for crude CPU based busy loop duration. The default
is assuming 1 GHz CPU and 2 cycles per loop. Reality is certainly
much worse but all we want here is a ball-park figure that ought
to be good enough for the purpose of being able to configure out
system timer support. If accuracy is very important then
implementing arch_busy_wait() should be considered.
config XIP
bool "Execute in place"
help

View file

@ -19,7 +19,7 @@ void z_impl_k_busy_wait(uint32_t usec_to_wait)
#if defined(CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT)
arch_busy_wait(usec_to_wait);
#else
#elif defined(CONFIG_SYS_CLOCK_EXISTS)
uint32_t start_cycles = k_cycle_get_32();
/* use 64-bit math to prevent overflow when multiplying */
@ -37,6 +37,17 @@ void z_impl_k_busy_wait(uint32_t usec_to_wait)
break;
}
}
#else
/*
* Crude busy loop for the purpose of being able to configure out
* system timer support.
*/
unsigned int loops_per_usec = CONFIG_BUSYWAIT_CPU_LOOPS_PER_USEC;
unsigned int loops = loops_per_usec * usec_to_wait;
while (loops-- > 0) {
arch_nop();
}
#endif
SYS_PORT_TRACING_FUNC_EXIT(k_thread, busy_wait, usec_to_wait);