[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] Add host_set_time64 and host_adjust_time64
From: |
Samuel Thibault |
Subject: |
Re: [PATCH] Add host_set_time64 and host_adjust_time64 |
Date: |
Sat, 28 Jan 2023 08:40:32 +0100 |
User-agent: |
NeoMutt/20170609 (1.8.3) |
Applied, thanks!
Flavio Cruz, le sam. 28 janv. 2023 02:04:34 -0500, a ecrit:
> Same existing logic, just with 64 bits. Old RPCs are implemented by
> calling into the new RPCs.
> ---
> doc/mach.texi | 4 +--
> include/mach/mach_host.defs | 18 ++++++++++
> kern/mach_clock.c | 67 +++++++++++++++++++++++++++----------
> 3 files changed, 69 insertions(+), 20 deletions(-)
>
> diff --git a/doc/mach.texi b/doc/mach.texi
> index 53026d0b..23832443 100644
> --- a/doc/mach.texi
> +++ b/doc/mach.texi
> @@ -5649,11 +5649,11 @@ Get the current time as seen by @var{host}. On
> success, the time passed
> since the epoch is returned in @var{current_time}.
> @end deftypefun
>
> -@deftypefun kern_return_t host_set_time (@w{host_priv_t @var{host_priv}},
> @w{time_value_t @var{new_time}})
> +@deftypefun kern_return_t host_set_time64 (@w{host_priv_t @var{host_priv}},
> @w{time_value64_t @var{new_time}})
> Set the time of @var{host_priv} to @var{new_time}.
> @end deftypefun
>
> -@deftypefun kern_return_t host_adjust_time (@w{host_priv_t @var{host_priv}},
> @w{time_value_t @var{new_adjustment}}, @w{time_value_t *@var{old_adjustment}})
> +@deftypefun kern_return_t host_adjust_time (@w{host_priv_t @var{host_priv}},
> @w{time_value64_t @var{new_adjustment}}, @w{time_value64_t
> *@var{old_adjustment}})
> Arrange for the current time as seen by @var{host_priv} to be gradually
> changed by the adjustment value @var{new_adjustment}, and return the old
> adjustment value in @var{old_adjustment}.
> diff --git a/include/mach/mach_host.defs b/include/mach/mach_host.defs
> index 0674c859..223f4576 100644
> --- a/include/mach/mach_host.defs
> +++ b/include/mach/mach_host.defs
> @@ -360,3 +360,21 @@ routine host_get_boot_info(
> routine host_get_time64(
> host : host_t;
> out current_time : time_value64_t);
> +
> +/*
> + * Set the time on this host.
> + * Only available to privileged users.
> + */
> +routine host_set_time64(
> + host : host_t;
> + new_time : time_value64_t);
> +
> +/*
> + * Arrange for the time on this host to be gradually changed
> + * by an adjustment value, and return the old value.
> + * Only available to privileged users.
> + */
> +routine host_adjust_time64(
> + host_priv : host_priv_t;
> + in new_adjustment : time_value64_t;
> + out old_adjustment : time_value64_t);
> diff --git a/kern/mach_clock.c b/kern/mach_clock.c
> index 4b983fdd..0e3a2cf2 100644
> --- a/kern/mach_clock.c
> +++ b/kern/mach_clock.c
> @@ -64,8 +64,10 @@
> #include <kern/pc_sample.h>
> #endif
>
> +#define MICROSECONDS_IN_ONE_SECOND 1000000
> +
> int hz = HZ; /* number of ticks per second */
> -int tick = (1000000 / HZ); /* number of usec per tick */
> +int tick = (MICROSECONDS_IN_ONE_SECOND / HZ); /* number of
> usec per tick */
> time_value64_t time = { 0, 0 }; /* time since bootup
> (uncorrected) */
> unsigned long elapsed_ticks = 0; /* ticks elapsed since bootup */
>
> @@ -469,6 +471,14 @@ host_get_time64(const host_t host, time_value64_t
> *current_time)
> */
> kern_return_t
> host_set_time(const host_t host, time_value_t new_time)
> +{
> + time_value64_t new_time64;
> + TIME_VALUE_TO_TIME_VALUE64(&new_time, &new_time64);
> + return host_set_time64(host, new_time64);
> +}
> +
> +kern_return_t
> +host_set_time64(const host_t host, time_value64_t new_time)
> {
> spl_t s;
>
> @@ -481,14 +491,12 @@ host_set_time(const host_t host, time_value_t new_time)
> */
> thread_bind(current_thread(), master_processor);
> if (current_processor() != master_processor)
> - thread_block((void (*)) 0);
> + thread_block(thread_no_continuation);
> #endif /* NCPUS > 1 */
>
> s = splhigh();
> - time_value64_t new_time64;
> - TIME_VALUE_TO_TIME_VALUE64(&new_time, &new_time64);
> - clock_boottime_update(&new_time64);
> - time = new_time64;
> + clock_boottime_update(&new_time);
> + time = new_time;
> update_mapped_time(&time);
> resettodr();
> splx(s);
> @@ -500,7 +508,7 @@ host_set_time(const host_t host, time_value_t new_time)
> thread_bind(current_thread(), PROCESSOR_NULL);
> #endif /* NCPUS > 1 */
>
> - return (KERN_SUCCESS);
> + return(KERN_SUCCESS);
> }
>
> /*
> @@ -512,37 +520,60 @@ host_adjust_time(
> time_value_t new_adjustment,
> time_value_t *old_adjustment /* OUT */)
> {
> - time_value_t oadj;
> - unsigned int ndelta;
> + time_value64_t old_adjustment64;
> + time_value64_t new_adjustment64;
> + kern_return_t ret;
> +
> + TIME_VALUE_TO_TIME_VALUE64(&new_adjustment, &new_adjustment64);
> + ret = host_adjust_time64(host, new_adjustment64, &old_adjustment64);
> + if (ret == KERN_SUCCESS) {
> + TIME_VALUE64_TO_TIME_VALUE(&old_adjustment64, old_adjustment);
> + }
> + return ret;
> +}
> +
> +/*
> + * Adjust the time gradually.
> + */
> +kern_return_t
> +host_adjust_time64(
> + const host_t host,
> + time_value64_t new_adjustment,
> + time_value64_t *old_adjustment /* OUT */)
> +{
> + time_value64_t oadj;
> + uint64_t ndelta_microseconds;
> spl_t s;
>
> if (host == HOST_NULL)
> return (KERN_INVALID_HOST);
>
> - ndelta = new_adjustment.seconds * 1000000
> - + new_adjustment.microseconds;
> + /* Note we only adjust up to microsecond precision */
> + ndelta_microseconds = new_adjustment.seconds *
> MICROSECONDS_IN_ONE_SECOND
> + + new_adjustment.nanoseconds / 1000;
>
> #if NCPUS > 1
> thread_bind(current_thread(), master_processor);
> if (current_processor() != master_processor)
> - thread_block((void (*)) 0);
> + thread_block(thread_no_continuation);
> #endif /* NCPUS > 1 */
>
> s = splclock();
>
> - oadj.seconds = timedelta / 1000000;
> - oadj.microseconds = timedelta % 1000000;
> + oadj.seconds = timedelta / MICROSECONDS_IN_ONE_SECOND;
> + oadj.nanoseconds = (timedelta % MICROSECONDS_IN_ONE_SECOND) * 1000;
>
> if (timedelta == 0) {
> - if (ndelta > bigadj)
> + if (ndelta_microseconds > bigadj)
> tickdelta = 10 * tickadj;
> else
> tickdelta = tickadj;
> }
> - if (ndelta % tickdelta)
> - ndelta = ndelta / tickdelta * tickdelta;
> + /* Make ndelta_microseconds a multiple of tickdelta */
> + if (ndelta_microseconds % tickdelta)
> + ndelta_microseconds = ndelta_microseconds / tickdelta * tickdelta;
>
> - timedelta = ndelta;
> + timedelta = ndelta_microseconds;
>
> splx(s);
> #if NCPUS > 1
> --
> 2.39.0
>
>
--
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.