[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH Mach] kern: Add a mach host operation which returns elapsed time
From: |
Zhaoming Luo |
Subject: |
[PATCH Mach] kern: Add a mach host operation which returns elapsed time since bootup |
Date: |
Tue, 24 Dec 2024 09:57:51 +0800 |
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>
---
doc/mach.texi | 5 +++++
include/mach/mach_host.defs | 7 +++++++
include/mach/time_value.h | 2 ++
kern/mach_clock.c | 38 +++++++++++++++++++++++++++++++++++++
kern/mach_clock.h | 1 +
5 files changed, 53 insertions(+)
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 4b953650..4d4ee62d 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 }; /* time since bootup (uncorrected) */
+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)
diff --git a/kern/mach_clock.h b/kern/mach_clock.h
index 66903b8a..621397a7 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; /* time since bootup (uncorrected) */
+extern time_value64_t uptime; /* time since bootup */
typedef void timer_func_t(void *);
--
2.45.2
- [PATCH Mach] kern: Add a mach host operation which returns elapsed time since bootup,
Zhaoming Luo <=