1 | /* Copyright (C) 1991-2022 Free Software Foundation, Inc. |
2 | This file is part of the GNU C Library. |
3 | |
4 | The GNU C Library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Lesser General Public |
6 | License as published by the Free Software Foundation; either |
7 | version 2.1 of the License, or (at your option) any later version. |
8 | |
9 | The GNU C Library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public |
15 | License along with the GNU C Library; if not, see |
16 | <https://www.gnu.org/licenses/>. */ |
17 | |
18 | #include <errno.h> |
19 | #include <time.h> |
20 | #include <mach.h> |
21 | #include <assert.h> |
22 | #include <shlib-compat.h> |
23 | |
24 | /* Get the current time of day, putting it into *TS. |
25 | Returns 0 on success, -1 on errors. */ |
26 | int |
27 | __clock_gettime (clockid_t clock_id, struct timespec *ts) |
28 | { |
29 | mach_msg_type_number_t count; |
30 | error_t err; |
31 | |
32 | switch (clock_id) { |
33 | |
34 | case CLOCK_REALTIME: |
35 | { |
36 | /* __host_get_time can only fail if passed an invalid host_t. |
37 | __mach_host_self could theoretically fail (producing an |
38 | invalid host_t) due to resource exhaustion, but we assume |
39 | this will never happen. */ |
40 | time_value_t tv; |
41 | __host_get_time (__mach_host_self (), &tv); |
42 | TIME_VALUE_TO_TIMESPEC (&tv, ts); |
43 | return 0; |
44 | } |
45 | |
46 | case CLOCK_PROCESS_CPUTIME_ID: |
47 | { |
48 | struct time_value t = { .seconds = 0, .microseconds = 0 }; |
49 | struct task_basic_info bi; |
50 | struct task_thread_times_info tti; |
51 | |
52 | /* Dead threads CPU time. */ |
53 | count = TASK_BASIC_INFO_COUNT; |
54 | err = __task_info (__mach_task_self (), TASK_BASIC_INFO, |
55 | (task_info_t) &bi, &count); |
56 | if (err) |
57 | { |
58 | __set_errno(err); |
59 | return -1; |
60 | } |
61 | time_value_add (&t, &bi.user_time); |
62 | time_value_add (&t, &bi.system_time); |
63 | |
64 | /* Live threads CPU time. */ |
65 | count = TASK_EVENTS_INFO_COUNT; |
66 | err = __task_info (__mach_task_self (), TASK_THREAD_TIMES_INFO, |
67 | (task_info_t) &tti, &count); |
68 | if (err) |
69 | { |
70 | __set_errno(err); |
71 | return -1; |
72 | } |
73 | time_value_add (&t, &tti.user_time); |
74 | time_value_add (&t, &tti.system_time); |
75 | |
76 | TIME_VALUE_TO_TIMESPEC(&t, ts); |
77 | return 0; |
78 | } |
79 | |
80 | case CLOCK_THREAD_CPUTIME_ID: |
81 | { |
82 | struct thread_basic_info bi; |
83 | mach_port_t self = __mach_thread_self (); |
84 | |
85 | count = THREAD_BASIC_INFO_COUNT; |
86 | err = __thread_info (self, THREAD_BASIC_INFO, |
87 | (thread_info_t) &bi, &count); |
88 | __mach_port_deallocate (__mach_task_self (), self); |
89 | if (err) |
90 | { |
91 | __set_errno(err); |
92 | return -1; |
93 | } |
94 | time_value_add (&bi.user_time, &bi.system_time); |
95 | |
96 | TIME_VALUE_TO_TIMESPEC(&bi.user_time, ts); |
97 | return 0; |
98 | } |
99 | } |
100 | |
101 | errno = EINVAL; |
102 | return -1; |
103 | } |
104 | libc_hidden_def (__clock_gettime) |
105 | |
106 | versioned_symbol (libc, __clock_gettime, clock_gettime, GLIBC_2_17); |
107 | /* clock_gettime moved to libc in version 2.17; |
108 | old binaries may expect the symbol version it had in librt. */ |
109 | #if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17) |
110 | strong_alias (__clock_gettime, __clock_gettime_2); |
111 | compat_symbol (libc, __clock_gettime_2, clock_gettime, GLIBC_2_2); |
112 | #endif |
113 | |
114 | int |
115 | __clock_gettime64 (clockid_t clock_id, struct __timespec64 *ts64) |
116 | { |
117 | struct timespec ts; |
118 | int ret; |
119 | |
120 | ret = __clock_gettime (clock_id, &ts); |
121 | if (ret == 0) |
122 | *ts64 = valid_timespec_to_timespec64 (ts); |
123 | |
124 | return ret; |
125 | } |
126 | libc_hidden_def (__clock_gettime64) |
127 | |