This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: First draft of the Y2038 design document
- From: Joseph Myers <joseph at codesourcery dot com>
- To: Albert ARIBAUD <albert dot aribaud at 3adev dot fr>
- Cc: GNU C Library <libc-alpha at sourceware dot org>
- Date: Mon, 26 Oct 2015 13:32:57 +0000
- Subject: Re: First draft of the Y2038 design document
- Authentication-results: sourceware.org; auth=none
- References: <20151026001252 dot 590e09c1 dot albert dot aribaud at 3adev dot fr>
The following initial comments relate to version 23 of the wiki page.
I think the page should be more cleanly split into three parts: the glibc
API; the glibc ABI underlying it; and implementation issues.
Thus, you say "if __USE_TIME_BITS64 is defined, then for each 64-bit time
syscall introduced where a 32-bit version exists already, select the
64-bits version as the default". But this is confused. Syscalls are not
a source of APIs for glibc in this regard. Rather, for each *glibc API*
involving time_t (including via struct timespec or struct timeval or
struct stat or at further levels of indirection) there should be a new
version of that API / underlying ABI with 64-bit time_t support.
Sometimes there may be a corresponding new syscall, sometimes not; for
example, I expect the kernel code to provide only *statat versions of stat
syscalls so that the 64-bit time_t code in glibc needs to implement *stat
in terms of *statat, much like it does for newer architectures using the
generic syscall ABI.
I don't think the list of syscalls belongs on the wiki page at all. What
might make sense is a full list of glibc interfaces involving time_t,
directly or indirectly and covering both ABIs and APIs.
In addition, regarding the interface / implementation split, I don't see
anything mentioned regarding use of the new glibc interfaces on old
kernels. It's critical that they work (until 2038) on old kernels (in
glibc versions that haven't obsoleted support for those old kernel
versions). That is, all the implementations of new interfaces will need
to do
#ifdef __ASSUME_TIME64
/* Implementation using new syscalls. */
#else
/* Implementation trying new syscalls, falling back to old ones if they
fail with ENOSYS. */
#endif
with __ASSUME_TIME64 being defined in kernel-features.h based on the
--enable-kernel version. Only when glibc no longer supports older kernels
can some of these move into simple syscalls.list entries.
I don't understand your "Two different aspects must be separated here:
size and domain." at all. When time_t is 64-bit, all 64 bits are
significant. This is true now, both in glibc and in glibc / kernel
interfaces.
An important issue you don't mention is the type of microseconds /
nanoseconds fields in timeval / timespec. Those should continue to be
"long" where specified as such by POSIX. Now, if the kernel wants the
structure layout to be the same on 32-bit and 64-bit systems, then the
userspace structure must contain an explicit padding field (before the
long on big-endian systems, after it on little-endian) in the case where
long is 32-bit. Hopefully the kernel will properly treat that field as
padding; if not (if it treats the two fields as a 64-bit integer with all
64 bits significant), glibc must copy such structures when passing them to
the kernel, making sure to sign-extend the "long" field into the padding
field.
I am doubtful about the need for _TIME64_SOURCE and explicit interfaces
for 64-bit time_t. Do you have actual examples of software whose
maintainers wish to use such interfaces rather than using _TIME_BITS=64?
My preference would be: no new *time64 APIs. Rather, just have
_TIME_BITS=64 map interface foo to assembler name __foo_time64 along with
changing the types, on systems where 32-bit time_t is supported; on
systems where it isn't supported, _TIME_BITS=64 should make no changes to
ABIs or APIs (including C++ name mangling) at all.
If, however, there are actual use cases for such APIs, then: API
consistency means that systems that already have 64-bit time_t need to
have such interfaces - at the API level only, not the ABI level (at the
ABI level, a direct call to clock_gettime64 would map to clock_gettime as
assembler name). While systems that currently use 32-bit time_t should
map clock_gettime64 to __clock_gettime64 as assembler name (since we need
__clock_gettime64 exported in this case for namespace reasons, ABI
minimization indicates avoiding exporting clock_gettime64 as well).
Regarding *stat* - I think it's safest and simplest to keep the use of
*xstat* interfaces (so that only *xstat* are exported from shared
libraries) for the new interfaces, rather than have different interfaces
styles used in glibc depending on which time_t is in use.
--
Joseph S. Myers
joseph@codesourcery.com