]>
Commit | Line | Data |
---|---|---|
2f4f3bd4 | 1 | /* clock_getres -- Get the resolution of a POSIX clockid_t. Linux version. |
93a78ac4 | 2 | Copyright (C) 2003-2012 Free Software Foundation, Inc. |
ad0e8eb0 UD |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
59ba27a6 PE |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ | |
ad0e8eb0 UD |
18 | |
19 | #include <sysdep.h> | |
2f4f3bd4 | 20 | #include <errno.h> |
6ba85a6d | 21 | #include <time.h> |
2f4f3bd4 | 22 | #include "kernel-posix-cpu-timers.h" |
6ddd37a4 | 23 | #include <kernel-features.h> |
ad0e8eb0 | 24 | |
8c2e201b UD |
25 | #ifndef HAVE_CLOCK_GETRES_VSYSCALL |
26 | # undef INTERNAL_VSYSCALL | |
27 | # define INTERNAL_VSYSCALL INTERNAL_SYSCALL | |
28 | # undef INLINE_VSYSCALL | |
29 | # define INLINE_VSYSCALL INLINE_SYSCALL | |
30 | #else | |
31 | # include <bits/libc-vdso.h> | |
32 | #endif | |
ad0e8eb0 | 33 | |
2f4f3bd4 | 34 | #define SYSCALL_GETRES \ |
8c2e201b | 35 | retval = INLINE_VSYSCALL (clock_getres, 2, clock_id, res); \ |
2f4f3bd4 RM |
36 | break |
37 | ||
93a78ac4 JM |
38 | /* The REALTIME and MONOTONIC clock are definitely supported in the |
39 | kernel. */ | |
40 | #define SYSDEP_GETRES \ | |
2f4f3bd4 | 41 | SYSDEP_GETRES_CPUTIME \ |
ad0e8eb0 UD |
42 | case CLOCK_REALTIME: \ |
43 | case CLOCK_MONOTONIC: \ | |
89a4419c UD |
44 | case CLOCK_MONOTONIC_RAW: \ |
45 | case CLOCK_REALTIME_COARSE: \ | |
46 | case CLOCK_MONOTONIC_COARSE: \ | |
2f4f3bd4 RM |
47 | SYSCALL_GETRES |
48 | ||
ad0e8eb0 UD |
49 | #ifdef __NR_clock_getres |
50 | /* We handled the REALTIME clock here. */ | |
51 | # define HANDLED_REALTIME 1 | |
2f4f3bd4 RM |
52 | # define HANDLED_CPUTIME 1 |
53 | ||
54 | # if __ASSUME_POSIX_CPU_TIMERS > 0 | |
55 | ||
56 | # define SYSDEP_GETRES_CPU SYSCALL_GETRES | |
57 | # define SYSDEP_GETRES_CPUTIME /* Default catches them too. */ | |
58 | ||
59 | # else | |
60 | ||
61 | extern int __libc_missing_posix_cpu_timers attribute_hidden; | |
62 | ||
63 | static int | |
64 | maybe_syscall_getres_cpu (clockid_t clock_id, struct timespec *res) | |
65 | { | |
66 | int e = EINVAL; | |
67 | ||
68 | if (!__libc_missing_posix_cpu_timers) | |
69 | { | |
70 | INTERNAL_SYSCALL_DECL (err); | |
8c2e201b | 71 | int r = INTERNAL_VSYSCALL (clock_getres, err, 2, clock_id, res); |
2f4f3bd4 RM |
72 | if (!INTERNAL_SYSCALL_ERROR_P (r, err)) |
73 | return 0; | |
74 | ||
75 | e = INTERNAL_SYSCALL_ERRNO (r, err); | |
93a78ac4 | 76 | if (e == EINVAL) |
2f4f3bd4 | 77 | { |
93a78ac4 JM |
78 | /* Check whether the kernel supports CPU clocks at all. |
79 | If not, record it for the future. */ | |
80 | r = INTERNAL_VSYSCALL (clock_getres, err, 2, | |
81 | MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED), | |
82 | NULL); | |
83 | if (INTERNAL_SYSCALL_ERROR_P (r, err)) | |
84 | __libc_missing_posix_cpu_timers = 1; | |
2f4f3bd4 RM |
85 | } |
86 | } | |
87 | ||
88 | return e; | |
89 | } | |
90 | ||
91 | # define SYSDEP_GETRES_CPU \ | |
92 | retval = maybe_syscall_getres_cpu (clock_id, res); \ | |
93 | if (retval == 0) \ | |
94 | break; \ | |
95 | if (retval != EINVAL || !__libc_missing_posix_cpu_timers) \ | |
96 | { \ | |
97 | __set_errno (retval); \ | |
98 | retval = -1; \ | |
99 | break; \ | |
100 | } \ | |
101 | retval = -1 /* Otherwise continue on to the HP_TIMING version. */; | |
102 | ||
103 | static inline int | |
104 | maybe_syscall_getres_cputime (clockid_t clock_id, struct timespec *res) | |
105 | { | |
106 | return maybe_syscall_getres_cpu | |
107 | (clock_id == CLOCK_THREAD_CPUTIME_ID | |
108 | ? MAKE_THREAD_CPUCLOCK (0, CPUCLOCK_SCHED) | |
109 | : MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED), | |
110 | res); | |
111 | } | |
112 | ||
113 | # define SYSDEP_GETRES_CPUTIME \ | |
114 | case CLOCK_PROCESS_CPUTIME_ID: \ | |
115 | case CLOCK_THREAD_CPUTIME_ID: \ | |
116 | retval = maybe_syscall_getres_cputime (clock_id, res); \ | |
117 | if (retval == 0) \ | |
118 | break; \ | |
119 | if (retval != EINVAL || !__libc_missing_posix_cpu_timers) \ | |
120 | { \ | |
121 | __set_errno (retval); \ | |
122 | retval = -1; \ | |
123 | break; \ | |
124 | } \ | |
125 | retval = hp_timing_getres (res); \ | |
126 | break; | |
127 | # if !HP_TIMING_AVAIL | |
128 | # define hp_timing_getres(res) (__set_errno (EINVAL), -1) | |
129 | # endif | |
130 | ||
131 | # endif | |
ad0e8eb0 UD |
132 | #endif |
133 | ||
134 | #include <sysdeps/posix/clock_getres.c> |