diff options
author | Zhaoming Luo <zhmingluo@163.com> | 2024-12-24 09:57:51 +0800 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2024-12-29 02:22:29 +0100 |
commit | fc494bfe3fb6363e1077dc035eb119970d84a9d1 (patch) | |
tree | 271db20499a280503ad5b046436fd9dd54dd5b25 | |
parent | 0bd3b64ff3af9a7c1b65bafb5cbf5189c52dc85a (diff) | |
download | gnumach-fc494bfe3fb6363e1077dc035eb119970d84a9d1.tar.gz gnumach-fc494bfe3fb6363e1077dc035eb119970d84a9d1.tar.bz2 gnumach-fc494bfe3fb6363e1077dc035eb119970d84a9d1.zip |
kern: Add a mach host operation which returns elapsed time since bootup
Add host_get_uptime64() mach interface operation. It can be used to get
the time passed since the boot up.
* doc/mach.texi: Add the documentation for the operation
* include/mach/mach_host.defs: Add the interface
* include/mach/time_value.h: Extend the mappable time variable
* kern/mach_clock.c: Operation implementation
* kern/mach_clock.h: Add a new variable for storing uptime
Signed-off-by: Zhaoming Luo <zhmingluo@163.com>
Message-ID: <20241224015751.1282-1-zhmingluo@163.com>
-rw-r--r-- | doc/mach.texi | 5 | ||||
-rw-r--r-- | include/mach/mach_host.defs | 7 | ||||
-rw-r--r-- | include/mach/time_value.h | 2 | ||||
-rw-r--r-- | kern/mach_clock.c | 39 | ||||
-rw-r--r-- | kern/mach_clock.h | 1 |
5 files changed, 54 insertions, 0 deletions
diff --git a/doc/mach.texi b/doc/mach.texi index f85288e0..f54ed655 100644 --- a/doc/mach.texi +++ b/doc/mach.texi @@ -5664,6 +5664,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_get_uptime64 (@w{host_t @var{host}}, @w{time_value64_t *@var{uptime}}) +Get the elapsed time since the boot up as seen by @var{host}. On success, the time passed +since the boot up is returned in @var{uptime}. +@end deftypefun + @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 diff --git a/include/mach/mach_host.defs b/include/mach/mach_host.defs index 8fd9d6b3..501ca0f6 100644 --- a/include/mach/mach_host.defs +++ b/include/mach/mach_host.defs @@ -386,3 +386,10 @@ routine host_adjust_time64( routine host_get_kernel_version( host : host_t; out kernel_version : new_kernel_version_t); + +/* + * Get the uptime on this host. + */ +routine host_get_uptime64( + host : host_t; + out uptime : time_value64_t); diff --git a/include/mach/time_value.h b/include/mach/time_value.h index e08707bc..7378c2cf 100644 --- a/include/mach/time_value.h +++ b/include/mach/time_value.h @@ -172,6 +172,8 @@ typedef struct mapped_time_value { integer_t check_seconds; struct time_value64 time_value; int64_t check_seconds64; + struct time_value64 uptime_value; + int64_t check_upseconds64; } mapped_time_value_t; /* Macros for converting between struct timespec and time_value_t. */ diff --git a/kern/mach_clock.c b/kern/mach_clock.c index 24609353..5501b7b8 100644 --- a/kern/mach_clock.c +++ b/kern/mach_clock.c @@ -69,6 +69,7 @@ int hz = HZ; /* number of ticks per second */ int tick = (MICROSECONDS_IN_ONE_SECOND / HZ); /* number of usec per tick */ time_value64_t time = { 0, 0 }; /* wallclock time (unadjusted) */ +time_value64_t uptime = { 0, 0 }; /* time since bootup */ unsigned long elapsed_ticks = 0; /* ticks elapsed since bootup */ int timedelta = 0; @@ -109,6 +110,17 @@ MACRO_BEGIN \ } \ MACRO_END +#define update_mapped_uptime(uptime) \ +MACRO_BEGIN \ + if (mtime != 0) { \ + mtime->check_upseconds64 = (uptime)->seconds; \ + __sync_synchronize(); \ + mtime->uptime_value.nanoseconds = (uptime)->nanoseconds;\ + __sync_synchronize(); \ + mtime->uptime_value.seconds = (uptime)->seconds; \ + } \ +MACRO_END + #define read_mapped_time(time) \ MACRO_BEGIN \ do { \ @@ -119,6 +131,16 @@ MACRO_BEGIN \ } while ((time)->seconds != mtime->check_seconds64); \ MACRO_END +#define read_mapped_uptime(uptime) \ +MACRO_BEGIN \ + do { \ + (uptime)->seconds = mtime->uptime_value.seconds; \ + __sync_synchronize(); \ + (uptime)->nanoseconds = mtime->uptime_value.nanoseconds;\ + __sync_synchronize(); \ + } while ((uptime)->seconds != mtime->check_upseconds64); \ +MACRO_END + def_simple_lock_irq_data(static, timer_lock) /* lock for ... */ timer_elt_data_t timer_head; /* ordered list of timeouts */ /* (doubles as end-of-list) */ @@ -230,6 +252,7 @@ void clock_interrupt( */ if (timedelta == 0) { time_value64_add_nanos(&time, usec * 1000); + time_value64_add_nanos(&uptime, usec * 1000); } else { int delta; @@ -251,8 +274,10 @@ void clock_interrupt( timedelta -= tickdelta; } time_value64_add_nanos(&time, delta * 1000); + time_value64_add_nanos(&uptime, delta * 1000); } update_mapped_time(&time); + update_mapped_uptime(&uptime); /* * Schedule soft-interrupt for timeout if needed @@ -571,6 +596,19 @@ host_adjust_time64( return (KERN_SUCCESS); } +/* + * Read the uptime (the elapsed time since boot up). + */ +kern_return_t +host_get_uptime64(const host_t host, time_value64_t *uptime) +{ + if (host == HOST_NULL) + return (KERN_INVALID_HOST); + + read_mapped_uptime(uptime); + return (KERN_SUCCESS); +} + void mapable_time_init(void) { if (kmem_alloc_wired(kernel_map, (vm_offset_t *) &mtime, PAGE_SIZE) @@ -578,6 +616,7 @@ void mapable_time_init(void) panic("mapable_time_init"); memset((void *) mtime, 0, PAGE_SIZE); update_mapped_time(&time); + update_mapped_uptime(&uptime); } int timeopen(dev_t dev, int flag, io_req_t ior) diff --git a/kern/mach_clock.h b/kern/mach_clock.h index 04ed4b99..d4f04f5e 100644 --- a/kern/mach_clock.h +++ b/kern/mach_clock.h @@ -41,6 +41,7 @@ extern int hz; /* number of ticks per second */ extern int tick; /* number of usec per tick */ extern time_value64_t time; /* wallclock time (unadjusted) */ +extern time_value64_t uptime; /* time since bootup */ typedef void timer_func_t(void *); |