aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlavio Cruz <flaviocruz@gmail.com>2023-01-28 02:04:34 -0500
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-01-28 08:40:25 +0100
commita8fbf3737be9a6f5fd1d87765072292d54e54aac (patch)
treee65ed8ce9cecc5d108b4dfbb86904405c4056b69
parentaafaddc3ba9b14a319153aaff0a7f0d333ef3637 (diff)
downloadgnumach-a8fbf3737be9a6f5fd1d87765072292d54e54aac.tar.gz
gnumach-a8fbf3737be9a6f5fd1d87765072292d54e54aac.tar.bz2
gnumach-a8fbf3737be9a6f5fd1d87765072292d54e54aac.zip
Add host_set_time64 and host_adjust_time64
Same existing logic, just with 64 bits. Old RPCs are implemented by calling into the new RPCs. Message-Id: <Y9TJAmL2byOWup5x@jupiter.tail36e24.ts.net>
-rw-r--r--doc/mach.texi4
-rw-r--r--include/mach/mach_host.defs18
-rw-r--r--kern/mach_clock.c67
3 files changed, 69 insertions, 20 deletions
diff --git a/doc/mach.texi b/doc/mach.texi
index 53026d0b..3fdba3fc 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_time64 (@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 */
@@ -470,6 +472,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;
if (host == HOST_NULL)
@@ -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