From 5a619c1f46c49dbb9706beeb74f4a466696394fc Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 11 Oct 2020 13:59:01 +0000 Subject: [PATCH] hurd: support clock_gettime(CLOCK_PROCESS/THREAD_CPUTIME_ID) * sysdeps/mach/clock_gettime.c (__clock_gettime): Add support for CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID. --- sysdeps/mach/clock_gettime.c | 86 ++++++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 13 deletions(-) diff --git a/sysdeps/mach/clock_gettime.c b/sysdeps/mach/clock_gettime.c index fbd80536d5..840e06036b 100644 --- a/sysdeps/mach/clock_gettime.c +++ b/sysdeps/mach/clock_gettime.c @@ -25,20 +25,80 @@ int __clock_gettime (clockid_t clock_id, struct timespec *ts) { - if (clock_id != CLOCK_REALTIME) - { - errno = EINVAL; - return -1; - } + mach_msg_type_number_t count; + error_t err; - /* __host_get_time can only fail if passed an invalid host_t. - __mach_host_self could theoretically fail (producing an - invalid host_t) due to resource exhaustion, but we assume - this will never happen. */ - time_value_t tv; - __host_get_time (__mach_host_self (), &tv); - TIME_VALUE_TO_TIMESPEC (&tv, ts); - return 0; + switch (clock_id) { + + case CLOCK_REALTIME: + { + /* __host_get_time can only fail if passed an invalid host_t. + __mach_host_self could theoretically fail (producing an + invalid host_t) due to resource exhaustion, but we assume + this will never happen. */ + time_value_t tv; + __host_get_time (__mach_host_self (), &tv); + TIME_VALUE_TO_TIMESPEC (&tv, ts); + return 0; + } + + case CLOCK_PROCESS_CPUTIME_ID: + { + struct time_value t = { .seconds = 0, .microseconds = 0 }; + struct task_basic_info bi; + struct task_thread_times_info tti; + + /* Dead threads CPU time. */ + count = TASK_BASIC_INFO_COUNT; + err = __task_info (__mach_task_self (), TASK_BASIC_INFO, + (task_info_t) &bi, &count); + if (err) + { + __set_errno(err); + return -1; + } + time_value_add (&t, &bi.user_time); + time_value_add (&t, &bi.system_time); + + /* Live threads CPU time. */ + count = TASK_EVENTS_INFO_COUNT; + err = __task_info (__mach_task_self (), TASK_THREAD_TIMES_INFO, + (task_info_t) &tti, &count); + if (err) + { + __set_errno(err); + return -1; + } + time_value_add (&t, &tti.user_time); + time_value_add (&t, &tti.system_time); + + TIME_VALUE_TO_TIMESPEC(&t, ts); + return 0; + } + + case CLOCK_THREAD_CPUTIME_ID: + { + struct thread_basic_info bi; + mach_port_t self = __mach_thread_self (); + + count = THREAD_BASIC_INFO_COUNT; + err = __thread_info (self, THREAD_BASIC_INFO, + (thread_info_t) &bi, &count); + __mach_port_deallocate (__mach_task_self (), self); + if (err) + { + __set_errno(err); + return -1; + } + time_value_add (&bi.user_time, &bi.system_time); + + TIME_VALUE_TO_TIMESPEC(&bi.user_time, ts); + return 0; + } + } + + errno = EINVAL; + return -1; } libc_hidden_def (__clock_gettime)