bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH gnumach] Track task and thread time using time_value64_t.


From: Flavio Cruz
Subject: [PATCH gnumach] Track task and thread time using time_value64_t.
Date: Mon, 13 Mar 2023 01:42:12 -0400

Changed kern/timer.c to use the higher precision time_value64_t.
Of course, this won't suffer from the 2038 overflow but it does provide
nanosecond precision (if gnumach ever uses a better timer) and
moves us closer to only having time_value64_t.
---
 include/mach/time_value.h |  5 +++
 kern/mach_clock.c         |  7 ++--
 kern/mach_clock.h         |  2 +-
 kern/task.c               | 42 ++++++++++----------
 kern/task.h               |  4 +-
 kern/thread.c             | 19 +++++----
 kern/timer.c              | 82 ++++++++++++++++-----------------------
 kern/timer.h              | 24 +++---------
 8 files changed, 81 insertions(+), 104 deletions(-)

diff --git a/include/mach/time_value.h b/include/mach/time_value.h
index 0643b740..ea661ec3 100644
--- a/include/mach/time_value.h
+++ b/include/mach/time_value.h
@@ -140,6 +140,11 @@ static __inline__ time_value_t 
convert_time_value_from_user(rpc_time_value_t tv)
     time_value64_sub_nanos(result, (subtrahend)->nanoseconds); \
   }
 
+#define time_value64_init(tv)  {                                               
                                                \
+               (tv)->seconds = 0;                                              
                                                                                
\
+               (tv)->nanoseconds = 0;                                          
                                                                \
+       }
+
 #define TIME_VALUE64_TO_TIME_VALUE(tv64, tv) do {                      \
                (tv)->seconds = (tv64)->seconds;                                
                                        \
                (tv)->microseconds = (tv64)->nanoseconds / 1000;        \
diff --git a/kern/mach_clock.c b/kern/mach_clock.c
index e33404a2..65c38086 100644
--- a/kern/mach_clock.c
+++ b/kern/mach_clock.c
@@ -428,11 +428,10 @@ record_time_stamp(time_value64_t *stamp)
  * real-time clock frame.
  */
 void
-read_time_stamp (const time_value64_t *stamp, rpc_time_value_t *result)
+read_time_stamp (const time_value64_t *stamp, time_value64_t *result)
 {
-       time_value64_t result64 = *stamp;
-       time_value64_sub(&result64, &clock_boottime_offset);
-       TIME_VALUE64_TO_TIME_VALUE(&result64, result);
+       *result = *stamp;
+       time_value64_sub(result, &clock_boottime_offset);
 }
 
 
diff --git a/kern/mach_clock.h b/kern/mach_clock.h
index 60b49b8a..66903b8a 100644
--- a/kern/mach_clock.h
+++ b/kern/mach_clock.h
@@ -98,7 +98,7 @@ extern void record_time_stamp (time_value64_t *stamp);
  * Read a timestamp in STAMP into RESULT.  Returns values in the
  * real-time clock frame.
  */
-extern void read_time_stamp (const time_value64_t *stamp, rpc_time_value_t 
*result);
+extern void read_time_stamp (const time_value64_t *stamp, time_value64_t 
*result);
 
 extern void mapable_time_init (void);
 
diff --git a/kern/task.c b/kern/task.c
index be385a1b..65191f5d 100644
--- a/kern/task.c
+++ b/kern/task.c
@@ -154,10 +154,8 @@ task_create_kernel(
        ipc_task_init(new_task, parent_task);
        machine_task_init (new_task);
 
-       new_task->total_user_time.seconds = 0;
-       new_task->total_user_time.microseconds = 0;
-       new_task->total_system_time.seconds = 0;
-       new_task->total_system_time.microseconds = 0;
+       time_value64_init(&new_task->total_user_time);
+       time_value64_init(&new_task->total_system_time);
 
        record_time_stamp (&new_task->creation_time);
 
@@ -808,16 +806,13 @@ kern_return_t task_info(
                task_lock(task);
                basic_info->base_priority = task->priority;
                basic_info->suspend_count = task->user_stop_count;
-               basic_info->user_time.seconds
-                               = task->total_user_time.seconds;
-               basic_info->user_time.microseconds
-                               = task->total_user_time.microseconds;
-               basic_info->system_time.seconds
-                               = task->total_system_time.seconds;
-               basic_info->system_time.microseconds
-                               = task->total_system_time.microseconds;
-               read_time_stamp(&task->creation_time,
-                               &basic_info->creation_time);
+               TIME_VALUE64_TO_TIME_VALUE(&task->total_user_time,
+                               &basic_info->user_time);
+               TIME_VALUE64_TO_TIME_VALUE(&task->total_system_time,
+                               &basic_info->system_time);
+               time_value64_t creation_time64;
+               read_time_stamp(&task->creation_time, &creation_time64);
+               TIME_VALUE64_TO_TIME_VALUE(&creation_time64, 
&basic_info->creation_time);
                task_unlock(task);
 
                if (*task_info_count > TASK_BASIC_INFO_COUNT)
@@ -854,21 +849,22 @@ kern_return_t task_info(
                task_thread_times_info_t times_info;
                thread_t        thread;
 
-               if (*task_info_count < TASK_THREAD_TIMES_INFO_COUNT) {
+               /* Callers might not known about time_value64_t fields yet. */
+               if (*task_info_count < TASK_THREAD_TIMES_INFO_COUNT - (2 * 
sizeof(time_value64_t)) / sizeof(integer_t)) {
                    return KERN_INVALID_ARGUMENT;
                }
 
                times_info = (task_thread_times_info_t) task_info_out;
-               times_info->user_time.seconds = 0;
-               times_info->user_time.microseconds = 0;
-               times_info->system_time.seconds = 0;
-               times_info->system_time.microseconds = 0;
+
+               time_value64_t acc_user_time, acc_system_time;
+               time_value64_init(&acc_user_time);
+               time_value64_init(&acc_system_time);
 
                task_lock(task);
                queue_iterate(&task->thread_list, thread,
                              thread_t, thread_list)
                {
-                   time_value_t user_time, system_time;
+                   time_value64_t user_time, system_time;
                    spl_t                s;
 
                    s = splsched();
@@ -879,10 +875,12 @@ kern_return_t task_info(
                    thread_unlock(thread);
                    splx(s);
 
-                   time_value_add(&times_info->user_time, &user_time);
-                   time_value_add(&times_info->system_time, &system_time);
+                   time_value64_add(&acc_user_time, &user_time);
+                   time_value64_add(&acc_system_time, &system_time);
                }
                task_unlock(task);
+               TIME_VALUE64_TO_TIME_VALUE(&acc_user_time, 
&times_info->user_time);
+               TIME_VALUE64_TO_TIME_VALUE(&acc_system_time, 
&times_info->system_time);
 
                *task_info_count = TASK_THREAD_TIMES_INFO_COUNT;
                break;
diff --git a/kern/task.h b/kern/task.h
index 38aa9feb..dec3a530 100644
--- a/kern/task.h
+++ b/kern/task.h
@@ -82,9 +82,9 @@ struct task {
        int             priority;               /* for new threads */
 
        /* Statistics */
-       time_value_t    total_user_time;
+       time_value64_t  total_user_time;
                                /* total user time for dead threads */
-       time_value_t    total_system_time;
+       time_value64_t  total_system_time;
                                /* total system time for dead threads */
 
        time_value64_t  creation_time; /* time stamp at creation */
diff --git a/kern/thread.c b/kern/thread.c
index 4a6b9eda..392d38f8 100644
--- a/kern/thread.c
+++ b/kern/thread.c
@@ -592,7 +592,7 @@ void thread_deallocate(
        task_t          task;
        processor_set_t pset;
 
-       time_value_t    user_time, system_time;
+       time_value64_t  user_time, system_time;
 
        if (thread == THREAD_NULL)
                return;
@@ -669,8 +669,8 @@ void thread_deallocate(
         *      Accumulate times for dead threads in task.
         */
        thread_read_times(thread, &user_time, &system_time);
-       time_value_add(&task->total_user_time, &user_time);
-       time_value_add(&task->total_system_time, &system_time);
+       time_value64_add(&task->total_user_time, &user_time);
+       time_value64_add(&task->total_system_time, &system_time);
 
        /*
         *      Remove thread from task list and processor_set threads list.
@@ -1522,13 +1522,16 @@ kern_return_t thread_info(
 
            /* fill in info */
 
-           thread_read_times_rpc(thread,
-                       &basic_info->user_time,
-                       &basic_info->system_time);
+           time_value64_t user_time, system_time;
+           thread_read_times(thread, &user_time, &system_time);
+           TIME_VALUE64_TO_TIME_VALUE(&user_time, &basic_info->user_time);
+           TIME_VALUE64_TO_TIME_VALUE(&system_time, &basic_info->system_time);
+
            basic_info->base_priority   = thread->priority;
            basic_info->cur_priority    = thread->sched_pri;
-           read_time_stamp(&thread->creation_time,
-                           &basic_info->creation_time);
+           time_value64_t creation_time;
+           read_time_stamp(&thread->creation_time, &creation_time);
+           TIME_VALUE64_TO_TIME_VALUE(&creation_time, 
&basic_info->creation_time);
 
            /*
             *  To calculate cpu_usage, first correct for timer rate,
diff --git a/kern/timer.c b/kern/timer.c
index 3b81ab79..7d029b7c 100644
--- a/kern/timer.c
+++ b/kern/timer.c
@@ -378,8 +378,13 @@ static void timer_grab(
        } while ( (save)->high != (timer)->high_bits_check);
 }
 
+#define TIMER_TO_TIME_VALUE64(tv, timer) do {                                  
                \
+               (tv)->seconds = (timer)->high + (timer)->low / 1000000; \
+               (tv)->nanoseconds = (timer)->low % 1000000 * 1000;              
        \
+} while(0);
+
 /*
- *     timer_read reads the value of a timer into a time_value_t.  If the
+ *     timer_read reads the value of a timer into a time_value64_t.  If the
  *     timer was modified during the read, retry.  The value returned
  *     is accurate to the last update; time accumulated by a running
  *     timer since its last timestamp is not included.
@@ -388,7 +393,7 @@ static void timer_grab(
 void
 timer_read(
        timer_t         timer,
-       time_value_t    *tv)
+       time_value64_t  *tv)
 {
        timer_save_data_t       temp;
 
@@ -399,9 +404,7 @@ timer_read(
 #ifdef TIMER_ADJUST
        TIMER_ADJUST(&temp);
 #endif /* TIMER_ADJUST */
-       tv->seconds = temp.high + temp.low/1000000;
-       tv->microseconds = temp.low%1000000;
-
+       TIMER_TO_TIME_VALUE64(tv, &temp);
 }
 
 /*
@@ -414,29 +417,11 @@ timer_read(
  */
 void   thread_read_times(
        thread_t        thread,
-       time_value_t    *user_time_p,
-       time_value_t    *system_time_p)
+       time_value64_t  *user_time_p,
+       time_value64_t  *system_time_p)
 {
-       timer_save_data_t       temp;
-       timer_t                 timer;
-
-       timer = &thread->user_timer;
-       timer_grab(timer, &temp);
-
-#ifdef TIMER_ADJUST
-       TIMER_ADJUST(&temp);
-#endif /* TIMER_ADJUST */
-       user_time_p->seconds = temp.high + temp.low/1000000;
-       user_time_p->microseconds = temp.low % 1000000;
-
-       timer = &thread->system_timer;
-       timer_grab(timer, &temp);
-
-#ifdef TIMER_ADJUST
-       TIMER_ADJUST(&temp);
-#endif /* TIMER_ADJUST */
-       system_time_p->seconds = temp.high + temp.low/1000000;
-       system_time_p->microseconds = temp.low % 1000000;
+       timer_read(&thread->user_timer, user_time_p);
+       timer_read(&thread->system_timer, system_time_p);
 }
 
 #if    MACH_DEBUG
@@ -458,6 +443,23 @@ static void db_timer_grab(
   (save)->low = (timer)->low_bits;
 }
 
+static void
+nonblocking_timer_read(
+       timer_t         timer,
+       time_value64_t  *tv)
+{
+       timer_save_data_t       temp;
+
+       db_timer_grab(timer, &temp);
+       /*
+        *      Normalize the result
+        */
+#ifdef TIMER_ADJUST
+       TIMER_ADJUST(&temp);
+#endif /* TIMER_ADJUST */
+       TIMER_TO_TIME_VALUE64(tv, &temp);
+}
+
 /*
  *      Db_thread_read_times: A version of thread_read_times that
  *      can be called by the debugger. This version does not call
@@ -467,29 +469,11 @@ static void db_timer_grab(
  */
 void   db_thread_read_times(
        thread_t        thread,
-       time_value_t    *user_time_p,
-       time_value_t    *system_time_p)
+       time_value64_t  *user_time_p,
+       time_value64_t  *system_time_p)
 {
-       timer_save_data_t       temp;
-       timer_t                 timer;
-
-       timer = &thread->user_timer;
-       db_timer_grab(timer, &temp);
-
-#ifdef TIMER_ADJUST
-       TIMER_ADJUST(&temp);
-#endif /* TIMER_ADJUST */
-       user_time_p->seconds = temp.high + temp.low/1000000;
-       user_time_p->microseconds = temp.low % 1000000;
-
-       timer = &thread->system_timer;
-       timer_grab(timer, &temp);
-
-#ifdef TIMER_ADJUST
-       TIMER_ADJUST(&temp);
-#endif /* TIMER_ADJUST */
-       system_time_p->seconds = temp.high + temp.low/1000000;
-       system_time_p->microseconds = temp.low % 1000000;
+       nonblocking_timer_read(&thread->user_timer, user_time_p);
+       nonblocking_timer_read(&thread->system_timer, system_time_p);
 }
 #endif  /* MACH_DEBUG */
 
diff --git a/kern/timer.h b/kern/timer.h
index 89790230..92259a2b 100644
--- a/kern/timer.h
+++ b/kern/timer.h
@@ -32,7 +32,7 @@
 #if    STAT_TIME
 /*
  *     Statistical timer definitions - use microseconds in timer, seconds
- *     in high unit field.  No adjustment needed to convert to time_value_t
+ *     in high unit field.  No adjustment needed to convert to time_value64_t
  *     as a result.  Service timers once an hour.
  */
 
@@ -56,7 +56,7 @@
 
 /*
  *     TIMER_ADJUST is used to adjust the value of a timer after it has been
- *     copied into a time_value_t.  No adjustment is needed if high_bits is in
+ *     copied into a time_value64_t.  No adjustment is needed if high_bits is 
in
  *     seconds.
  */
 #undef TIMER_ADJUST
@@ -128,24 +128,12 @@ extern void       start_timer(timer_t);
 extern void    timer_switch(timer_t);
 #endif /* STAT_TIME */
 
-extern void            timer_read(timer_t, time_value_t *);
-extern void            thread_read_times(thread_t, time_value_t *, 
time_value_t *);
+extern void            timer_read(timer_t, time_value64_t *);
+extern void            thread_read_times(thread_t, time_value64_t *, 
time_value64_t *);
 extern unsigned                timer_delta(timer_t, timer_save_t);
 extern void            timer_normalize(timer_t);
 extern void            timer_init(timer_t);
 
-static inline void
-thread_read_times_rpc(thread_t thread,
-                      rpc_time_value_t *user_time_p, rpc_time_value_t 
*system_time_p)
-{
-  time_value_t user_p, system_p;
-  thread_read_times(thread, &user_p, &system_p);
-  user_time_p->seconds = user_p.seconds;
-  user_time_p->microseconds = user_p.microseconds;
-  system_time_p->seconds = system_p.seconds;
-  system_time_p->microseconds = system_p.microseconds;
-}
-
 #if    STAT_TIME
 /*
  *     Macro to bump timer values.
@@ -199,8 +187,8 @@ void timer_init(timer_t this_timer);
 #if    MACH_DEBUG
 void   db_thread_read_times(
        thread_t        thread,
-       time_value_t    *user_time_p,
-       time_value_t    *system_time_p);
+       time_value64_t  *user_time_p,
+       time_value64_t  *system_time_p);
 #endif
 
 
-- 
2.39.2




reply via email to

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