aboutsummaryrefslogtreecommitdiff
path: root/kern
diff options
context:
space:
mode:
authorZhaoming Luo <zhmingluo@163.com>2024-12-24 09:57:51 +0800
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2024-12-29 02:22:29 +0100
commitfc494bfe3fb6363e1077dc035eb119970d84a9d1 (patch)
tree271db20499a280503ad5b046436fd9dd54dd5b25 /kern
parent0bd3b64ff3af9a7c1b65bafb5cbf5189c52dc85a (diff)
downloadgnumach-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>
Diffstat (limited to 'kern')
-rw-r--r--kern/mach_clock.c39
-rw-r--r--kern/mach_clock.h1
2 files changed, 40 insertions, 0 deletions
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 *);