summaryrefslogtreecommitdiff
path: root/src/time/clock_gettime.c
AgeCommit message (Collapse)AuthorLines
2022-09-19re-enable vdso clock_gettime on arm (32-bit) with workaroundRich Felker-0/+3
commit 4486c579cbf0d989080705f515d08cb48636ba88 disabled vdso clock_gettime on arm due to a Linux kernel bug that was not understood at the time, whereby the vdso function silently produced catastrophically wrong results on some systems. since then, the bug was tracked down to the way the arm kernel disabled use of vdso clock_gettime on kernels where the necessary timer was not available or was disabled. it simply patched out the symbols, but it only did this for the legacy time32 functions, and left the time64 function in place but non-operational. kernel commit 4405bdf3c57ec28d606bdf5325f1167505bfdcd4 (first present in 5.8) provided the fix. if this were a bug that impacted all users of the broken kernel versions, we could probably ignore it and assume it had been patched or replaced. however, it's very possible that these kernels appear in the wild in devices running time32 userspace (glibc, musl 1.1.x, or some other environment) where they appear to work fine, but where our new binaries would fail catastrophically if we used the time64 vdso function. since the kernel has not (yet?) given us a way to probe for the working time64 vdso function semantically, we work around the problem by refusing to use the time64 one unless the time32 one is also present. this will revert to not using vdso at all if the time32 one is ever removed, but at least that's safe against wrong results and is just a missed optimization.
2022-05-01only fallback to gettimeofday/settimeofday syscalls if they existStefan O'Rear-0/+4
riscv32 and future architectures only provide the clock_ functions.
2019-08-05fix regression in clock_gettime on 32-bit archs without vdsoRich Felker-0/+1
commit 72f50245d018af0c31b38dec83c557a4e5dd1ea8 broke this by creating a code path where r is uninitialized.
2019-08-02clock_gettime: add support for 32-bit vdso with 64-bit time_tRich Felker-0/+32
this fixes a major upcoming performance regression introduced by commit 72f50245d018af0c31b38dec83c557a4e5dd1ea8, whereby 32-bit archs would lose vdso clock_gettime after switching to 64-bit time_t, unless the kernel supports time64 and provides a time64 version of the vdso function. this would incur not just one but two syscalls: first, the failed time64 syscall, then the fallback time32 one. overflow of the 32-bit result is detected and triggers a revert to syscalls. normally, on a system that's not Y2038-ready, this would still overflow, but if the process has been migrated to a time64-capable kernel or if the kernel has been hot-patched to add time64 syscalls, it may conceivably work.
2019-08-02clock_gettime: add time64 syscall support, decouple 32-bit time_tRich Felker-0/+19
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.
2018-09-12reduce spurious inclusion of libc.hRich Felker-1/+0
libc.h was intended to be a header for access to global libc state and related interfaces, but ended up included all over the place because it was the way to get the weak_alias macro. most of the inclusions removed here are places where weak_alias was needed. a few were recently introduced for hidden. some go all the way back to when libc.h defined CANCELPT_BEGIN and _END, and all (wrongly implemented) cancellation points had to include it. remaining spurious users are mostly callers of the LOCK/UNLOCK macros and files that use the LFS64 macro to define the awful *64 aliases. in a few places, new inclusion of libc.h is added because several internal headers no longer implicitly include libc.h. declarations for __lockfile and __unlockfile are moved from libc.h to stdio_impl.h so that the latter does not need libc.h. putting them in libc.h made no sense at all, since the macros in stdio_impl.h are needed to use them correctly anyway.
2018-09-12move and deduplicate declarations of __vdsosym to make it checkableRich Felker-2/+0
2016-01-27improve clock_gettime and adapt it to support slightly-broken vdsoRich Felker-22/+39
these changes are motivated by a functionally similar patch by Hauke Mehrtens to address the needs of the new mips vdso clock_gettime, which wrongly fails with ENOSYS rather than falling back to making a syscall for clock ids it cannot handle from userspace. in the process of preparing to handle that case, it was noticed that the old clock_gettime use of the vdso was actually wrong with respect to error handling -- the tail call to the vdso function failed to set errno and instead returned an error code. since tail calls to vdso are no longer possible and since the plain syscall code is now needed as a fallback path anyway, it does not make sense to use a function pointer to call the plain syscall code path. instead, it's inlined at the end of the main clock_gettime function. the new code also avoids the need to test for initialization of the vdso function pointer by statically initializing it to a self-init function, and eliminates redundant loads from the volatile pointer object. finally, the use of a_cas_p on an object of type other than void *, which is not permitted aliasing, is replaced by using an object with the correct type and casting the value.
2015-03-03make all objects used with atomic operations volatileRich Felker-1/+1
the memory model we use internally for atomics permits plain loads of values which may be subject to concurrent modification without requiring that a special load function be used. since a compiler is free to make transformations that alter the number of loads or the way in which loads are performed, the compiler is theoretically free to break this usage. the most obvious concern is with atomic cas constructs: something of the form tmp=*p;a_cas(p,tmp,f(tmp)); could be transformed to a_cas(p,*p,f(*p)); where the latter is intended to show multiple loads of *p whose resulting values might fail to be equal; this would break the atomicity of the whole operation. but even more fundamental breakage is possible. with the changes being made now, objects that may be modified by atomics are modeled as volatile, and the atomic operations performed on them by other threads are modeled as asynchronous stores by hardware which happens to be acting on the request of another thread. such modeling of course does not itself address memory synchronization between cores/cpus, but that aspect was already handled. this all seems less than ideal, but it's the best we can do without mandating a C11 compiler and using the C11 model for atomics. in the case of pthread_once_t, the ABI type of the underlying object is not volatile-qualified. so we are assuming that accessing the object through a volatile-qualified lvalue via casts yields volatile access semantics. the language of the C standard is somewhat unclear on this matter, but this is an assumption the linux kernel also makes, and seems to be the correct interpretation of the standard.
2014-04-16add working vdso clock_gettime support, including static linkingRich Felker-5/+13
the vdso symbol lookup code is based on the original 2011 patch by Nicholas J. Kain, with some streamlining, pointer arithmetic fixes, and one symbol version matching fix. on the consumer side (clock_gettime), per-arch macros for the particular symbol name and version to lookup are added in syscall_arch.h, and no vdso code is pulled in on archs which do not define these macros. at this time, vdso is enabled only on x86_64. the vdso support at the dynamic linker level is no longer useful to libc, but is left in place for the sake of debuggers (which may need the vdso in the link map to find its functions) and possibly use with dlsym.
2014-04-14fix fallback code for old kernels in clock_gettimeRich Felker-1/+1
2011-08-07use weak aliase rather than weak reference for vdso clock_gettimeRich Felker-8/+12
this works around pcc's lack of working support for weak references, and in principle is nice because it gets us back to the stage where the only weak symbol feature we use is weak aliases, nothing else. having fewer dependencies on fancy linker features is a good thing.
2011-07-24workaround for gcc's optimizer breaking dynamic symbol resolutionRich Felker-1/+2
2011-07-24const correctness on function pointerRich Felker-1/+1
2011-07-23some preliminaries for vdso clock supportRich Felker-2/+23
these changes also make it so clock_gettime(CLOCK_REALTIME, &ts) works even on pre-2.6 kernels, emulated via the gettimeofday syscall. there is no cost for the fallback check, as it falls under the error case that already must be checked for storing the error code in errno, but which would normally be hidden inside __syscall_ret.
2011-03-20global cleanup to use the new syscall interfaceRich Felker-1/+1
2011-03-10fix errno behavior in clock_* functionsRich Felker-1/+0
these functions are specified inconsistent in whether they're specified to return an error value, or return -1 and set errno. hopefully now they all match what POSIX requires.
2011-02-19implement the remaining clock_* interfacesRich Felker-0/+1
2011-02-12initial check-in, version 0.5.0v0.5.0Rich Felker-0/+7