native: hw_timer: add an absolute deadline for the tick interrupt - #14
native: hw_timer: add an absolute deadline for the tick interrupt#14npitre wants to merge 1 commit into
Conversation
The tick interrupt can only be had as a period, via hwtimer_enable(), with hwtimer_set_silent_ticks() to pass over the expiries not wanted. Most real timers are not that shape: the ARM architected timer is a free running counter plus an absolute compare (CNTVCT_EL0, CNTV_CVAL_EL0), and the RISC-V machine timer is mtime plus mtimecmp. Both fire once the counter reaches or passes the compare. A driver for either holds an absolute deadline, and here has to round it onto the period grid or reprogram the period on every timeout. hwtimer_set_tick_deadline() raises the same interrupt when simulated time reaches an absolute time, which nsi_hws_get_time() already hands out. A deadline already passed fires at once and NSI_NEVER cancels. It uses an event of its own, so the periodic tick, the awake timer and the real time pacing are untouched. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
aescolar
left a comment
There was a problem hiding this comment.
@npitre would you be so kind as to say what is it that you want to achieve that is not achieved already by using the enable api for this same purpose?
(I did consider adding a one shot api, but the implementation would certainly not have been like this.)
|
What I want is: Just like many hardware implementations do. With the enable API a driver holding an absolute deadline has to turn it back You say you considered a one shot and would not have implemented it this way: |
|
That can be added.
So you don't want the Zephyr driver to use timer_driver_set_reload()?
That is a misunderstanding. That issue is already fixed, that other tick timer driver change can now be resubmitted as it was in Zephyr with the native simulator as it is in main. |
|
Fair on the regression, the coupling was the cause and you have fixed it. I On What is it you do not like in the implementation here? Happy to respin it, or |
|
@npitre if you have use a one shot API like the one proposed in this API, how will the zephyr driver look instead of the using the current |
|
The bulk of it: /* Microseconds of simulated time since boot. Never wraps. */
static uint64_t timer_driver_cycle_get(void)
{
return nsi_hws_get_time();
}
/* The model fires at once for a deadline already passed, hence ORDERED. */
static void timer_driver_set_compare(uint64_t cycles)
{
hwtimer_set_tick_deadline(cycles);
}
/* Knobs for system_timer_generic.h */
#define TIMER_CORE_BACKEND_COMPARE_ORDERED
#define TIMER_CORE_COUNTER_WIDTH 64
#include "system_timer_generic.h"
static void np_timer_isr(const void *arg)
{
ARG_UNUSED(arg);
timer_core_announce();
}The ordered compare is also the arrangement with the least overhead: the core |
RFC. Adds a second way to program the tick interrupt: an absolute deadline,
rather than a period plus a count of expiries to skip.
The motivation is fidelity to the hardware being modelled. A free running
counter plus an absolute compare, firing once the counter reaches or passes it,
is what the ARM architected timer (
CNTVCT_EL0/CNTV_CVAL_EL0) and theRISC-V machine timer (
mtime/mtimecmp) are, and the model already hands outexactly that counter as
nsi_hws_get_time(). What it does not expose is thecompare, so a guest driver written for that shape has to convert its deadline
into a count of periods to skip, which rounds it onto the period grid, or
reprogram the period on every timeout so that one period is the delay it wants.
Tested by converting Zephyr's native_sim timer driver to use it, on top of
0d3eafc:
hello_worldpaces correctly (--stop_at=2in 2 s of wall clock), anoffloaded socket blocking on a peer that replies after 2 real seconds advances
simulated time by 2010 ms, and
tests/kernelis 2732/2732 on bothnative_simand
native_sim/native/64.Open questions:
hwtimer_wake_in_time()is the existing absolute-time call, sohwtimer_tick_in_time()would be symmetric. But the semantics differdeliberately:
wake_in_timekeeps the earlier of two requests, this onereplaces.
hwtimer_enable()already clearssilent_ticksand could clear this too.