bug-hurd
[Top][All Lists]
Advanced

[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




reply via email to

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