Damien Zammit via Bug reports for the GNU Hurd, le dim. 23 mars 2025 10:20:37 +0000, a ecrit: > You probably want to disable it entirely so it doesn't need to execute a > branch condition every time it reads the timer, ie with #ifdef.
The if is precisely meant for the case where hpet is not available even if apic is, at runtime. > This code path would be critical for timing. At this point in the code, we have already paid the cost of an interrupt or a system call. An if is really neglectible here. Samuel > Sent from Proton Mail Android > > > -------- Original Message -------- > On 23/3/25 9:13 pm, Zhaoming Luo <zhming...@163.com> wrote: > > > Hi, > > > > I'm wondering the code for checking whether a high-precision code is > > available should be in mach_clock.c or in the machine-dependent > > directory. In this patch it's in the machine-dependent directory. It can > > ensure the backward compactability. Otherwise compiling a gnumach with > > only '../configure' will cause page fault at the startup. > > ``` > > +uint32_t > > +hpclock_read_counter(void) > > +{ > > + if (hpet_addr != NULL) > > + return HPET32(HPET_COUNTER); > > + else > > + return 0; > > +} > > + > > +uint32_t > > +hpclock_get_counter_period_nsec(void) > > +{ > > + if (hpet_addr != NULL) > > + return hpet_period_nsec; > > + else > > + return 0; > > +} > > ``` > > > > Zhaoming > > --- > > i386/i386/apic.c | 17 +++++++++++++++++ > > i386/i386at/model_dep.c | 2 ++ > > kern/mach_clock.c | 36 +++++++++++++++++++++++++++++++++++- > > kern/mach_clock.h | 4 ++++ > > 4 files changed, 58 insertions(+), 1 deletion(-) > > > > diff --git a/i386/i386/apic.c b/i386/i386/apic.c > > index 77d555b5..6cacd5fa 100644 > > --- a/i386/i386/apic.c > > +++ b/i386/i386/apic.c > > @@ -479,3 +479,20 @@ hpet_mdelay(uint32_t ms) > > hpet_udelay(ms * 1000); > > } > > > > +uint32_t > > +hpclock_read_counter(void) > > +{ > > + if (hpet_addr != NULL) > > + return HPET32(HPET_COUNTER); > > + else > > + return 0; > > +} > > + > > +uint32_t > > +hpclock_get_counter_period_nsec(void) > > +{ > > + if (hpet_addr != NULL) > > + return hpet_period_nsec; > > + else > > + return 0; > > +} > > diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c > > index 30449c37..42dadeb8 100644 > > --- a/i386/i386at/model_dep.c > > +++ b/i386/i386at/model_dep.c > > @@ -223,7 +223,9 @@ void machine_init(void) > > */ > > gdt_descr_tmp.linear_base += apboot_addr; > > apboot_jmp_offset += apboot_addr; > > +#endif > > > > +#ifdef APIC > > /* > > * Initialize the HPET > > */ > > diff --git a/kern/mach_clock.c b/kern/mach_clock.c > > index 5501b7b8..9bae3439 100644 > > --- a/kern/mach_clock.c > > +++ b/kern/mach_clock.c > > @@ -83,6 +83,15 @@ unsigned tickadj = 500 / HZ; /* can adjust > > 100 usecs per second */ > > unsigned bigadj = 1000000; /* adjust 10*tickadj if adjustment > > > bigadj */ > > > > +/* A high-precision (hardware) clock is taken into account to increase the > > + * accuracy of the functions used for getting time (e.g. > > host_get_time64()). > > + * The counter of the clock is read once in every clock interrupt. When > > any > > + * of the functions used for getting time is called, the counter is read > > again > > + * and the difference between these two read is multiplied by the counter > > + * period and added to the read value from time or uptime to get a more > > + * accurate time read. */ > > +uint32_t last_hpc_read = 0; > > + > > /* > > * This update protocol, with a check value, allows > > * do { > > @@ -128,7 +137,8 @@ MACRO_BEGIN > > \ > > __sync_synchronize(); \ > > (time)->nanoseconds = mtime->time_value.nanoseconds; \ > > __sync_synchronize(); \ > > - } while ((time)->seconds != mtime->check_seconds64); \ > > + } while ((time)->seconds != mtime->check_seconds64); \ > > + time_value64_add_hpc(time); \ > > MACRO_END > > > > #define read_mapped_uptime(uptime) > > \ > > @@ -139,6 +149,7 @@ MACRO_BEGIN > > \ > > (uptime)->nanoseconds = mtime->uptime_value.nanoseconds;\ > > __sync_synchronize(); \ > > } while ((uptime)->seconds != mtime->check_upseconds64); \ > > + time_value64_add_hpc(uptime); \ > > MACRO_END > > > > def_simple_lock_irq_data(static, timer_lock) /* lock for ... */ > > @@ -292,6 +303,7 @@ void clock_interrupt( > > } > > } > > } > > + last_hpc_read = hpclock_read_counter(); > > } > > > > /* > > @@ -426,6 +438,28 @@ clock_boottime_update(const struct time_value64 > > *new_time) > > time_value64_add(&clock_boottime_offset, &delta); > > } > > > > +/* > > + * Add the time value since last clock interrupt in nanosecond. > > + */ > > +static void > > +time_value64_add_hpc(time_value64_t *value) > > +{ > > + uint32_t now = hpclock_read_counter(); > > + /* Time since last clock interrupt in nanosecond. */ > > + int64_t ns = (now - last_hpc_read) * hpclock_get_counter_period_nsec(); > > + > > + /* Limit the value of ns under the period of a clock interrupt in case > > + imprecise computation causes ns greater than the clock interrupt > > + period. */ > > + if (ns > tick * 1000) > > + /* Let ns stuck at the end of the clock interrupt period when > > + something bad happens. */ > > + ns = (tick * 1000) - 1; > > + > > + time_value64_add_nanos(value, ns); > > +} > > + > > + > > /* > > * Record a timestamp in STAMP. Records values in the boot-time clock > > * frame. > > diff --git a/kern/mach_clock.h b/kern/mach_clock.h > > index d4f04f5e..e83b638c 100644 > > --- a/kern/mach_clock.h > > +++ b/kern/mach_clock.h > > @@ -110,4 +110,8 @@ extern boolean_t untimeout(timer_func_t *fcn, const > > void *param); > > extern int timeopen(dev_t dev, int flag, io_req_t ior); > > extern void timeclose(dev_t dev, int flag); > > > > +/* For high-precision clocks. */ > > +extern uint32_t hpclock_read_counter(void); > > +extern uint32_t hpclock_get_counter_period_nsec(void); > > + > > #endif /* _KERN_MACH_CLOCK_H_ */ > > -- > > 2.47.2 > > > > > > > -- Samuel /* * [...] Note that 120 sec is defined in the protocol as the maximum * possible RTT. I guess we'll have to use something other than TCP * to talk to the University of Mars. * PAWS allows us longer timeouts and large windows, so once implemented * ftp to mars will work nicely. */ (from /usr/src/linux/net/inet/tcp.c, concerning RTT [retransmission timeout])