bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Add host_set_time64 and host_adjust_time64


From: Flavio Cruz
Subject: [PATCH] Add host_set_time64 and host_adjust_time64
Date: Sat, 28 Jan 2023 02:04:34 -0500

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]