/* * Copyright (c) 2018 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include void z_impl_k_busy_wait(uint32_t usec_to_wait) { SYS_PORT_TRACING_FUNC_ENTER(k_thread, busy_wait, usec_to_wait); if (usec_to_wait == 0U) { SYS_PORT_TRACING_FUNC_EXIT(k_thread, busy_wait, usec_to_wait); return; } #if defined(CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT) arch_busy_wait(usec_to_wait); #elif defined(CONFIG_SYS_CLOCK_EXISTS) 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 ); for (;;) { uint32_t current_cycles = k_cycle_get_32(); /* this handles the rollover on an unsigned 32-bit value */ if ((current_cycles - start_cycles) >= cycles_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); } #ifdef CONFIG_USERSPACE static inline void z_vrfy_k_busy_wait(uint32_t usec_to_wait) { z_impl_k_busy_wait(usec_to_wait); } #include #endif /* CONFIG_USERSPACE */