mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 07:43:54 -06:00
clock: Introduce clock_ticks_to_ns()
The clock_get_ns() API claims to return the period of a clock in nanoseconds. Unfortunately since it returns an integer and a clock's period is represented in units of 2^-32 nanoseconds, the result is often an approximation, and calculating a clock expiry deadline by multiplying clock_get_ns() by a number-of-ticks is unacceptably inaccurate. Introduce a new API clock_ticks_to_ns() which returns the number of nanoseconds it takes the clock to make a given number of ticks. This function can do the complete calculation internally and will thus give a more accurate result. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Luc Michel <luc@lmichel.fr> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-Id: <20201215150929.30311-2-peter.maydell@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
This commit is contained in:
parent
7886a674f1
commit
554d523785
2 changed files with 70 additions and 0 deletions
|
@ -258,6 +258,35 @@ Here is an example:
|
|||
clock_get_ns(dev->my_clk_input));
|
||||
}
|
||||
|
||||
Calculating expiry deadlines
|
||||
----------------------------
|
||||
|
||||
A commonly required operation for a clock is to calculate how long
|
||||
it will take for the clock to tick N times; this can then be used
|
||||
to set a timer expiry deadline. Use the function ``clock_ticks_to_ns()``,
|
||||
which takes an unsigned 64-bit count of ticks and returns the length
|
||||
of time in nanoseconds required for the clock to tick that many times.
|
||||
|
||||
It is important not to try to calculate expiry deadlines using a
|
||||
shortcut like multiplying a "period of clock in nanoseconds" value
|
||||
by the tick count, because clocks can have periods which are not a
|
||||
whole number of nanoseconds, and the accumulated error in the
|
||||
multiplication can be significant.
|
||||
|
||||
For a clock with a very long period and a large number of ticks,
|
||||
the result of this function could in theory be too large to fit in
|
||||
a 64-bit value. To avoid overflow in this case, ``clock_ticks_to_ns()``
|
||||
saturates the result to INT64_MAX (because this is the largest valid
|
||||
input to the QEMUTimer APIs). Since INT64_MAX nanoseconds is almost
|
||||
300 years, anything with an expiry later than that is in the "will
|
||||
never happen" category. Callers of ``clock_ticks_to_ns()`` should
|
||||
therefore generally not special-case the possibility of a saturated
|
||||
result but just allow the timer to be set to that far-future value.
|
||||
(If you are performing further calculations on the returned value
|
||||
rather than simply passing it to a QEMUTimer function like
|
||||
``timer_mod_ns()`` then you should be careful to avoid overflow
|
||||
in those calculations, of course.)
|
||||
|
||||
Changing a clock period
|
||||
-----------------------
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue