sys: time_units: Add Kconfig option for algorithm selection
Add maximum timeout used for conversion to Kconfig. Option is used to determine which conversion algorithm to use: faster but overflowing earlier or slower without early overflow. Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
fb5334d2cf
commit
50c7c7b1e4
3 changed files with 37 additions and 0 deletions
|
@ -64,6 +64,21 @@ static TIME_CONSTEXPR inline int sys_clock_hw_cycles_per_sec(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* Macro determines if fast conversion algorithm can be used. It checks if
|
||||
* maximum timeout represented in source frequency domain and multiplied by
|
||||
* target frequency fits in 64 bits.
|
||||
*
|
||||
* @param from_hz Source frequency.
|
||||
* @param to_hz Target frequency.
|
||||
*
|
||||
* @retval true Use faster algorithm.
|
||||
* @retval false Use algorithm preventing overflow of intermediate value.
|
||||
*/
|
||||
#define Z_TMCVT_USE_FAST_ALGO(from_hz, to_hz) \
|
||||
((ceiling_fraction(CONFIG_SYS_CLOCK_MAX_TIMEOUT_DAYS * 24ULL * 3600ULL * from_hz, \
|
||||
UINT32_MAX) * to_hz) <= UINT32_MAX)
|
||||
|
||||
/* Time converter generator gadget. Selects from one of three
|
||||
* conversion algorithms: ones that take advantage when the
|
||||
* frequencies are an integer ratio (in either direction), or a full
|
||||
|
@ -131,7 +146,17 @@ static TIME_CONSTEXPR ALWAYS_INLINE uint64_t z_tmcvt(uint64_t t, uint32_t from_h
|
|||
} else {
|
||||
if (result32) {
|
||||
return (uint32_t)((t * to_hz + off) / from_hz);
|
||||
} else if (const_hz && Z_TMCVT_USE_FAST_ALGO(from_hz, to_hz)) {
|
||||
/* Faster algorithm but source is first multiplied by target frequency
|
||||
* and it can overflow even though final result would not overflow.
|
||||
* Kconfig option shall prevent use of this algorithm when there is a
|
||||
* risk of overflow.
|
||||
*/
|
||||
return ((t * to_hz + off) / from_hz);
|
||||
} else {
|
||||
/* Slower algorithm but input is first divided before being multiplied
|
||||
* which prevents overflow of intermediate value.
|
||||
*/
|
||||
return (t / from_hz) * to_hz + ((t % from_hz) * to_hz + off) / from_hz;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -644,6 +644,17 @@ config TIMEOUT_64BIT
|
|||
availability of absolute timeout values (which require the
|
||||
extra precision).
|
||||
|
||||
config SYS_CLOCK_MAX_TIMEOUT_DAYS
|
||||
int "Max timeout (in days) used in conversions"
|
||||
default 365
|
||||
help
|
||||
Value is used in the time conversion static inline function to determine
|
||||
at compile time which algorithm to use. One algorithm is faster, takes
|
||||
less code but may overflow if multiplication of source and target
|
||||
frequency exceeds 64 bits. Second algorithm prevents that. Faster
|
||||
algorithm is selected for conversion if maximum timeout represented in
|
||||
source frequency domain multiplied by target frequency fits in 64 bits.
|
||||
|
||||
config XIP
|
||||
bool "Execute in place"
|
||||
help
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#define CONFIG_MP_NUM_CPUS 1
|
||||
#define CONFIG_SYS_CLOCK_TICKS_PER_SEC 100
|
||||
#define CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC 10000000
|
||||
#define CONFIG_SYS_CLOCK_MAX_TIMEOUT_DAYS 365
|
||||
#define ARCH_STACK_PTR_ALIGN 8
|
||||
/* FIXME: Properly integrate with Zephyr's arch specific code */
|
||||
#define CONFIG_X86 1
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue