mirror of
git://git.musl-libc.org/musl
synced 2025-01-20 22:00:56 +00:00
clock_gettime: add time64 syscall support, decouple 32-bit time_t
the time64 syscall has to be used if time_t is 64-bit, since there's no way of knowing before making a syscall whether the result will fit in 32 bits, and the 32-bit syscalls do not report overflow as an error. on 64-bit archs, there is no change to the code after preprocessing. on current 32-bit archs, the result is now read from the kernel through long[2] array, then copied into the timespec, to remove the assumption that time_t is the same as long. vdso clock_gettime is still used in place of a syscall if available. 32-bit archs with 64-bit time_t must use the time64 version of the vdso function; if it's not available, performance will significantly suffer. support for both vdso functions could be added, but would break the ability to move a long-lived process from a pre-time64 kernel to one that can outlast Y2038 with checkpoint/resume, at least without added hacks to identify that the 32-bit function is no longer usable and stop using it (e.g. by seeing negative tv_sec). this possibility may be explored in future work on the function.
This commit is contained in:
parent
2b4fd6f75b
commit
72f50245d0
@ -40,6 +40,24 @@ int __clock_gettime(clockid_t clk, struct timespec *ts)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SYS_clock_gettime64
|
||||
if (sizeof(time_t) > 4)
|
||||
r = __syscall(SYS_clock_gettime64, clk, ts);
|
||||
if (SYS_clock_gettime == SYS_clock_gettime64 || r!=-ENOSYS)
|
||||
return __syscall_ret(r);
|
||||
long ts32[2];
|
||||
r = __syscall(SYS_clock_gettime, clk, ts32);
|
||||
if (r==-ENOSYS && clk==CLOCK_REALTIME) {
|
||||
r = __syscall(SYS_gettimeofday, ts32, 0);
|
||||
ts32[1] *= 1000;
|
||||
}
|
||||
if (!r) {
|
||||
ts->tv_sec = ts32[0];
|
||||
ts->tv_nsec = ts32[1];
|
||||
return r;
|
||||
}
|
||||
return __syscall_ret(r);
|
||||
#else
|
||||
r = __syscall(SYS_clock_gettime, clk, ts);
|
||||
if (r == -ENOSYS) {
|
||||
if (clk == CLOCK_REALTIME) {
|
||||
@ -50,6 +68,7 @@ int __clock_gettime(clockid_t clk, struct timespec *ts)
|
||||
r = -EINVAL;
|
||||
}
|
||||
return __syscall_ret(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
weak_alias(__clock_gettime, clock_gettime);
|
||||
|
Loading…
Reference in New Issue
Block a user