1 /* clock_gettime -- Get current time from a POSIX clockid_t. Linux version.
2 Copyright (C) 2003, 2004 Free Software Foundation, Inc.
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
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
18
19 #include <errno.h>
20 #include <sysdep.h>
21 #include <time.h>
22 #include <sys/time.h>
23 #include "kernel-posix-cpu-timers.h"
24
25 #ifdef __VDSO_SUPPORT__
26 #include "ldso.h"
27 #endif
28
29 #if defined(__UCLIBC_USE_TIME64__)
30 #include "internal/time64_helpers.h"
31 #endif
32
33 #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64)
34 #define SYSCALL_GETTIME \
35 { \
36 struct __ts64_struct __ts64; \
37 retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, &__ts64); \
38 if (tp) { \
39 tp->tv_sec = __ts64.tv_sec; \
40 tp->tv_nsec = __ts64.tv_nsec; \
41 } \
42 break; \
43 }
44 #else
45 #define SYSCALL_GETTIME \
46 retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \
47 break
48 #endif
49
50 /* The REALTIME and MONOTONIC clock are definitely supported in the kernel. */
51 #define SYSDEP_GETTIME \
52 SYSDEP_GETTIME_CPUTIME \
53 case CLOCK_REALTIME: \
54 case CLOCK_MONOTONIC: \
55 SYSCALL_GETTIME
56
57 /* We handled the REALTIME clock here. */
58 #define HANDLED_REALTIME 1
59 #define HANDLED_CPUTIME 1
60
61 #define SYSDEP_GETTIME_CPU SYSCALL_GETTIME
62 #define SYSDEP_GETTIME_CPUTIME /* Default catches them too. */
63
64 static inline int
realtime_gettime(struct timespec * tp)65 realtime_gettime (struct timespec *tp)
66 {
67 struct timeval tv;
68 int retval = gettimeofday (&tv, NULL);
69 if (retval == 0)
70 /* Convert into `timespec'. */
71 TIMEVAL_TO_TIMESPEC (&tv, tp);
72 return retval;
73 }
74
75 int
__libc_clock_gettime(clockid_t clock_id,struct timespec * tp)76 __libc_clock_gettime (clockid_t clock_id, struct timespec *tp)
77 {
78 int retval = -1;
79 #ifndef HANDLED_REALTIME
80 struct timeval tv;
81 #endif
82
83 switch (clock_id)
84 {
85 #ifdef SYSDEP_GETTIME
86 SYSDEP_GETTIME;
87 #endif
88
89 #ifndef HANDLED_REALTIME
90 case CLOCK_REALTIME:
91 retval = gettimeofday (&tv, NULL);
92 if (retval == 0)
93 TIMEVAL_TO_TIMESPEC (&tv, tp);
94 break;
95 #endif
96
97 default:
98 #ifdef SYSDEP_GETTIME_CPU
99 SYSDEP_GETTIME_CPU;
100 #endif
101 __set_errno (EINVAL);
102 break;
103 }
104
105 return retval;
106 }
107
108 /* Get current value of CLOCK and store it in TP. */
109 int
clock_gettime(clockid_t clock_id,struct timespec * tp)110 clock_gettime (clockid_t clock_id, struct timespec *tp)
111 {
112 #if defined(__VDSO_SUPPORT__) && defined(ARCH_VDSO_CLOCK_GETTIME)
113 return ARCH_VDSO_CLOCK_GETTIME(clock_id, tp);
114 #else
115 return __libc_clock_gettime(clock_id, tp);
116 #endif
117 }
118