9 static void *volatile vdso_func
;
11 static int cgt_init(clockid_t clk
, struct timespec
*ts
)
13 void *p
= __vdsosym(VDSO_CGT_VER
, VDSO_CGT_SYM
);
14 int (*f
)(clockid_t
, struct timespec
*) =
15 (int (*)(clockid_t
, struct timespec
*))p
;
16 a_cas_p(&vdso_func
, (void *)cgt_init
, p
);
17 return f
? f(clk
, ts
) : -ENOSYS
;
20 static void *volatile vdso_func
= (void *)cgt_init
;
24 int __clock_gettime(clockid_t clk
, struct timespec
*ts
)
29 int (*f
)(clockid_t
, struct timespec
*) =
30 (int (*)(clockid_t
, struct timespec
*))vdso_func
;
34 if (r
== -EINVAL
) return __syscall_ret(r
);
35 /* Fall through on errors other than EINVAL. Some buggy
36 * vdso implementations return ENOSYS for clocks they
37 * can't handle, rather than making the syscall. This
38 * also handles the case where cgt_init fails to find
39 * a vdso function to use. */
43 #ifdef SYS_clock_gettime64
44 if (sizeof(time_t) > 4)
45 r
= __syscall(SYS_clock_gettime64
, clk
, ts
);
46 if (SYS_clock_gettime
== SYS_clock_gettime64
|| r
!=-ENOSYS
)
47 return __syscall_ret(r
);
49 r
= __syscall(SYS_clock_gettime
, clk
, ts32
);
50 if (r
==-ENOSYS
&& clk
==CLOCK_REALTIME
) {
51 r
= __syscall(SYS_gettimeofday
, ts32
, 0);
56 ts
->tv_nsec
= ts32
[1];
59 return __syscall_ret(r
);
61 r
= __syscall(SYS_clock_gettime
, clk
, ts
);
63 if (clk
== CLOCK_REALTIME
) {
64 __syscall(SYS_gettimeofday
, ts
, 0);
65 ts
->tv_nsec
= (int)ts
->tv_nsec
* 1000;
70 return __syscall_ret(r
);
74 weak_alias(__clock_gettime
, clock_gettime
);