Message ID | CAKmqyKOXtCQ68G0DxEcesbKQCWGaXpvMV2SX-hzDdJJaQ+J_cA@mail.gmail.com |
---|---|
State | Superseded |
Headers |
Received: (qmail 101521 invoked by alias); 18 Sep 2019 17:08:19 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: <libc-alpha.sourceware.org> List-Unsubscribe: <mailto:libc-alpha-unsubscribe-##L=##H@sourceware.org> List-Subscribe: <mailto:libc-alpha-subscribe@sourceware.org> List-Archive: <http://sourceware.org/ml/libc-alpha/> List-Post: <mailto:libc-alpha@sourceware.org> List-Help: <mailto:libc-alpha-help@sourceware.org>, <http://sourceware.org/ml/#faqs> Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 101513 invoked by uid 89); 18 Sep 2019 17:08:19 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.0 required=5.0 tests=AWL, BAYES_00, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: mail-lj1-f194.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=zGZB15MCmmUtbIIF6WqvhfSF65t0Q1xP7xY46aHGKMQ=; b=H/NyNHhX7nzKTgidMY54DtPbXplzRlYpTkTT68AzGBTCniFD5SMcpcjZEMl3uqOFQn 1/WN/JiDyLefrEdq8jgwB0CwQjtFF3sMP5ihHJxFIpsG1zQ7bGH+yx6VfZAYqdyYMwWV UB0YKgfxph3gDagCIoSAWzriz/uE3eCE79DLQUx7btOEkWJrt9DbeYVvqGX959dGFmcB fxHVwrwACNjhF3b7YyArIiWRqfjgYmnDRQzpWwFzowe7Bp0pcaKnzAw8Ffu/TizBLTVp BKPjqoOA/DwiQkCNSXVCiJeZLI3nEoAnElkXwnPgv/jl2K7lp6k1Eun2rjqXK/eKyqu1 G4YQ== MIME-Version: 1.0 References: <20190906145911.30207-1-lukma@denx.de> <CAKmqyKMdsVZg_ZS7fLTt23dy2vnZc1z85b_+8heiK-8UiqMx+g@mail.gmail.com> <alpine.DEB.2.21.1909062122220.30243@digraph.polyomino.org.uk> <CAKmqyKP=kmeJjcsDepetvsVrph3xJ7G8yQdNFNyX-wL2ZMtqmA@mail.gmail.com> <20190917121151.01629dad@jawa> <alpine.DEB.2.21.1909171332410.17687@digraph.polyomino.org.uk> <20190917175343.01715554@jawa> <alpine.DEB.2.21.1909171640200.25711@digraph.polyomino.org.uk> In-Reply-To: <alpine.DEB.2.21.1909171640200.25711@digraph.polyomino.org.uk> From: Alistair Francis <alistair23@gmail.com> Date: Wed, 18 Sep 2019 10:03:41 -0700 Message-ID: <CAKmqyKOXtCQ68G0DxEcesbKQCWGaXpvMV2SX-hzDdJJaQ+J_cA@mail.gmail.com> Subject: Re: [PATCH v7 0/3] y2038: Linux: Introduce __clock_settime64 function To: Joseph Myers <joseph@codesourcery.com> Cc: Lukasz Majewski <lukma@denx.de>, Zack Weinberg <zackw@panix.com>, Arnd Bergmann <arnd@arndb.de>, Alistair Francis <alistair.francis@wdc.com>, GNU C Library <libc-alpha@sourceware.org>, Adhemerval Zanella <adhemerval.zanella@linaro.org>, Florian Weimer <fweimer@redhat.com>, "Carlos O'Donell" <carlos@redhat.com>, Stepan Golosunov <stepan@golosunov.pp.ru> Content-Type: text/plain; charset="UTF-8" |
Commit Message
Alistair Francis
Sept. 18, 2019, 5:03 p.m. UTC
On Tue, Sep 17, 2019 at 9:51 AM Joseph Myers <joseph@codesourcery.com> wrote: > > On Tue, 17 Sep 2019, Lukasz Majewski wrote: > > > - New 32 bits glibc ports (like RISC-V 32) will get __TIMESIZE == > > 64 (__WORDSIZE == 32) and no need to define the -D_TIME_BITS=64 > > during the compilation. They will just get 64 bit time API support > > from the outset. > > Yes, at least if such ports wish to use 64-bit time; I don't think we've > really discussed if we want to *require* 64-bit time for future ports > (e.g. the next revised resubmissions of the ARC and NDS32 ports). > Certainly the work required right now for ARC or NDS32 to use 64-bit time > would be significantly more than the work for RV32 (because they also > support older kernel versions without the 64-bit-time syscalls, so all the > Y2038 work for fallback at runtime to older syscalls becomes relevant), > unless they decide on 5.1 or later as minimum kernel version. > > > - Already supported 32 bits architectures (like armv7-a with __WORDSIZE > > == 32) will keep __TIMESIZE == 32 and require -D_TIME_BITS=64 for > > compilation. > > Yes. > > > After glibc sets the minimal supported kernel version to 5.1 and all > > conversions for syscalls to support 64 bit time API are done the > > __TIMESIZE will be set to 64 and -D_TIME_BITS=64 will not be required > > anymore for compilation. > > No. __TIMESIZE means the size of time_t in the unsuffixed ABIs in glibc, > not the _TIME_BITS-dependent size of time_t in the current compilation. > We hope in future to make _TIME_BITS=64 the default and only API supported > for new compilations (which is independent of what the minimum kernel > version is), but __TIMESIZE would still be 32, because the unsuffixed ABIs > would remain compatible with existing binaries using 32-bit time. > > > Ok. So then we shall keep the condition: > > > > #if __WORDSIZE == 64 \ > > || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > > # define __timespec64 timespec > > #else > > No. __timespec64 should be defined to timespec whenever __TIMESIZE == 64. > The timespec to which it is defined, in the public header, would gain > padding. > > The condition > > #if __WORDSIZE == 64 \ > || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > > is correct as a condition for struct timespec (in the public header) *not* > to have padding. Are you going to incorporate this into your series Lukasz? I currently have this diff which fixes the build failures for me: As well as that the timeval struct has the same issue. I'll have to look into that and see what the solution is there. Alistair > > -- > Joseph S. Myers > joseph@codesourcery.com
Comments
On Wed, 18 Sep 2019, Alistair Francis wrote: > +#include <endian.h> > > /* POSIX.1b structure for a time value. This is like a `struct timeval' but > has nanoseconds instead of microseconds. */ > struct timespec > { > __time_t tv_sec; /* Seconds. */ > +#if __WORDSIZE == 64 \ > + || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > __syscall_slong_t tv_nsec; /* Nanoseconds. */ > +#else > +# if BYTE_ORDER == BIG_ENDIAN > + __int32_t tv_pad; /* Padding */ > + __syscall_slong_t tv_nsec; /* Nanoseconds */ > +# else > + __int32_t tv_nsec; /* Nanoseconds */ > + __syscall_slong_t tv_pad; /* Padding */ > +# endif > +#endif The padding must be an *unnamed bit-field* so that { tv_sec, tv_nsec } initializers (common in practice even if not officially supported by the standards) continue to work. Also, I think you should just use "long int" for tv_nsec in the case where there is padding, as the standard-defined type (and then the padding can be "int: 32", so avoiding any dependence on whether compilers support non-int bit-fields). Certainly the choice of types for tv_nsec and padding should not depend on the endianness (the patch above is using __int32_t for the first field and __syscall_slong_t for the second, regardless of which is tv_nsec and which is padding). There are namespace issues when changing installed headers. You can't use macros such as BYTE_ORDER or BIG_ENDIAN because they aren't in the standard-reserved namespaces. Unfortunately the definitions of __LITTLE_ENDIAN and __BIG_ENDIAN are in <endian.h> (__BYTE_ORDER is in the architecture-specific <bits/endian.h>), and while the non-reserved names therein are all conditional on __USE_MISC, I don't think we really want to start exporting them from every header that uses struct timespec. My inclination would be to have a separate bits/ header that only defines the __LITTLE_ENDIAN / __BIG_ENDIAN / __PDP_ENDIAN macros (or that defines those and includes the architecture-specific header for __BYTE_ORDER), so that other headers can test endianness without bringing in all the other __USE_MISC endian-related macros from <endian.h>, but Zack might advise on how such changes would fit into his header cleanups.
Hi Alistair, > On Tue, Sep 17, 2019 at 9:51 AM Joseph Myers > <joseph@codesourcery.com> wrote: > > > > On Tue, 17 Sep 2019, Lukasz Majewski wrote: > > > > > - New 32 bits glibc ports (like RISC-V 32) will get __TIMESIZE == > > > 64 (__WORDSIZE == 32) and no need to define the -D_TIME_BITS=64 > > > during the compilation. They will just get 64 bit time API > > > support from the outset. > > > > Yes, at least if such ports wish to use 64-bit time; I don't think > > we've really discussed if we want to *require* 64-bit time for > > future ports (e.g. the next revised resubmissions of the ARC and > > NDS32 ports). Certainly the work required right now for ARC or > > NDS32 to use 64-bit time would be significantly more than the work > > for RV32 (because they also support older kernel versions without > > the 64-bit-time syscalls, so all the Y2038 work for fallback at > > runtime to older syscalls becomes relevant), unless they decide on > > 5.1 or later as minimum kernel version. > > > - Already supported 32 bits architectures (like armv7-a with > > > __WORDSIZE == 32) will keep __TIMESIZE == 32 and require > > > -D_TIME_BITS=64 for compilation. > > > > Yes. > > > > > After glibc sets the minimal supported kernel version to 5.1 > > > and all conversions for syscalls to support 64 bit time API are > > > done the __TIMESIZE will be set to 64 and -D_TIME_BITS=64 will > > > not be required anymore for compilation. > > > > No. __TIMESIZE means the size of time_t in the unsuffixed ABIs in > > glibc, not the _TIME_BITS-dependent size of time_t in the current > > compilation. We hope in future to make _TIME_BITS=64 the default > > and only API supported for new compilations (which is independent > > of what the minimum kernel version is), but __TIMESIZE would still > > be 32, because the unsuffixed ABIs would remain compatible with > > existing binaries using 32-bit time. > > > Ok. So then we shall keep the condition: > > > > > > #if __WORDSIZE == 64 \ > > > || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > > > # define __timespec64 timespec > > > #else > > > > No. __timespec64 should be defined to timespec whenever __TIMESIZE > > == 64. The timespec to which it is defined, in the public header, > > would gain padding. > > > > The condition > > > > #if __WORDSIZE == 64 \ > > || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > > > > is correct as a condition for struct timespec (in the public > > header) *not* to have padding. > > Are you going to incorporate this into your series Lukasz? > > I currently have this diff which fixes the build failures for me: > > diff --git a/include/time.h b/include/time.h > index 7ed3aa61d1d..91f6280eb4d 100644 > --- a/include/time.h > +++ b/include/time.h > @@ -50,8 +50,7 @@ extern void __tzset_parse_tz (const char *tz) > attribute_hidden; > extern void __tz_compute (__time64_t timer, struct tm *tm, int > use_localtime) __THROW attribute_hidden; > > -#if __WORDSIZE == 64 \ > - || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > +#if __TIMESIZE == 64 I've prepared v8 of __clock_settime64 conversion patches with the above change: https://patchwork.ozlabs.org/cover/1164209/ I've tested it with meta-y2038: https://github.com/lmajewski/meta-y2038 as well as ../src/scripts/build-many-glibcs.py It seems to work as expected. > # define __timespec64 timespec > #else > /* The glibc Y2038-proof struct __timespec64 structure for a time > value. diff --git a/time/bits/types/struct_timespec.h > b/time/bits/types/struct_timespec.h > index 5b77c52b4f0..48405c4f08a 100644 > --- a/time/bits/types/struct_timespec.h > +++ b/time/bits/types/struct_timespec.h > @@ -3,13 +3,25 @@ > #define _STRUCT_TIMESPEC 1 > > #include <bits/types.h> > +#include <endian.h> > > /* POSIX.1b structure for a time value. This is like a `struct > timeval' but has nanoseconds instead of microseconds. */ > struct timespec > { > __time_t tv_sec; /* Seconds. */ > +#if __WORDSIZE == 64 \ > + || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > __syscall_slong_t tv_nsec; /* Nanoseconds. */ > +#else > +# if BYTE_ORDER == BIG_ENDIAN > + __int32_t tv_pad; /* Padding */ > + __syscall_slong_t tv_nsec; /* Nanoseconds */ > +# else > + __int32_t tv_nsec; /* Nanoseconds */ > + __syscall_slong_t tv_pad; /* Padding */ > +# endif > +#endif > }; I did not incorporated the above change to v8 of __clock_settime64 as there are some issues raised by Joseph. Last but not least - we can get away with the above change as the implicit padding works for RV32, and ARM32 (which both are LE). > > #endif > > As well as that the timeval struct has the same issue. I'll have to > look into that and see what the solution is there. > > Alistair > > > > > -- > > Joseph S. Myers > > joseph@codesourcery.com Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
Hi Joseph, > On Wed, 18 Sep 2019, Alistair Francis wrote: > > > +#include <endian.h> > > > > /* POSIX.1b structure for a time value. This is like a `struct > > timeval' but has nanoseconds instead of microseconds. */ > > struct timespec > > { > > __time_t tv_sec; /* Seconds. */ > > +#if __WORDSIZE == 64 \ > > + || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > > __syscall_slong_t tv_nsec; /* Nanoseconds. */ > > +#else > > +# if BYTE_ORDER == BIG_ENDIAN > > + __int32_t tv_pad; /* Padding */ > > + __syscall_slong_t tv_nsec; /* Nanoseconds */ > > +# else > > + __int32_t tv_nsec; /* Nanoseconds */ > > + __syscall_slong_t tv_pad; /* Padding */ > > +# endif > > +#endif > Just one more question - am I correct that the above code will increase the overall sizeof(struct timespec) to 12 for machines with __WORDSIZE == 32 ? I guess that now such machine have sizeof(struct timespec) = 8 ? However, this shouldn't be a problem (unless some user space SW uses this data in an unusual way...). > The padding must be an *unnamed bit-field* so that { tv_sec, tv_nsec > } initializers (common in practice even if not officially supported > by the standards) continue to work. Also, I think you should just > use "long int" for tv_nsec in the case where there is padding, as the > standard-defined type (and then the padding can be "int: 32", so > avoiding any dependence on whether compilers support non-int > bit-fields). Certainly the choice of types for tv_nsec and padding > should not depend on the endianness (the patch above is using > __int32_t for the first field and __syscall_slong_t for the second, > regardless of which is tv_nsec and which is padding). > > There are namespace issues when changing installed headers. You > can't use macros such as BYTE_ORDER or BIG_ENDIAN because they aren't > in the standard-reserved namespaces. > > Unfortunately the definitions of __LITTLE_ENDIAN and __BIG_ENDIAN are > in <endian.h> (__BYTE_ORDER is in the architecture-specific > <bits/endian.h>), and while the non-reserved names therein are all > conditional on __USE_MISC, I don't think we really want to start > exporting them from every header that uses struct timespec. My > inclination would be to have a separate bits/ header that only > defines the __LITTLE_ENDIAN / __BIG_ENDIAN / __PDP_ENDIAN macros (or > that defines those and includes the architecture-specific header for > __BYTE_ORDER), so that other headers can test endianness without > bringing in all the other __USE_MISC endian-related macros from > <endian.h>, but Zack might advise on how such changes would fit into > his header cleanups. > Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On Wed, 18 Sep 2019, Lukasz Majewski wrote: > Just one more question - am I correct that the above code will increase > the overall sizeof(struct timespec) to 12 for machines with __WORDSIZE > == 32 ? It looks like that's a bug in the patch, indeed. (The padding should *only* be added when __TIMESIZE == 64 in addition to the other conditions given, not when __TIMESIZE == 32.)
On Wed, Sep 18, 2019 at 2:28 PM Lukasz Majewski <lukma@denx.de> wrote: > > Hi Alistair, > > > On Tue, Sep 17, 2019 at 9:51 AM Joseph Myers > > <joseph@codesourcery.com> wrote: > > > > > > On Tue, 17 Sep 2019, Lukasz Majewski wrote: > > > > > > > - New 32 bits glibc ports (like RISC-V 32) will get __TIMESIZE == > > > > 64 (__WORDSIZE == 32) and no need to define the -D_TIME_BITS=64 > > > > during the compilation. They will just get 64 bit time API > > > > support from the outset. > > > > > > Yes, at least if such ports wish to use 64-bit time; I don't think > > > we've really discussed if we want to *require* 64-bit time for > > > future ports (e.g. the next revised resubmissions of the ARC and > > > NDS32 ports). Certainly the work required right now for ARC or > > > NDS32 to use 64-bit time would be significantly more than the work > > > for RV32 (because they also support older kernel versions without > > > the 64-bit-time syscalls, so all the Y2038 work for fallback at > > > runtime to older syscalls becomes relevant), unless they decide on > > > 5.1 or later as minimum kernel version. > > > > - Already supported 32 bits architectures (like armv7-a with > > > > __WORDSIZE == 32) will keep __TIMESIZE == 32 and require > > > > -D_TIME_BITS=64 for compilation. > > > > > > Yes. > > > > > > > After glibc sets the minimal supported kernel version to 5.1 > > > > and all conversions for syscalls to support 64 bit time API are > > > > done the __TIMESIZE will be set to 64 and -D_TIME_BITS=64 will > > > > not be required anymore for compilation. > > > > > > No. __TIMESIZE means the size of time_t in the unsuffixed ABIs in > > > glibc, not the _TIME_BITS-dependent size of time_t in the current > > > compilation. We hope in future to make _TIME_BITS=64 the default > > > and only API supported for new compilations (which is independent > > > of what the minimum kernel version is), but __TIMESIZE would still > > > be 32, because the unsuffixed ABIs would remain compatible with > > > existing binaries using 32-bit time. > > > > Ok. So then we shall keep the condition: > > > > > > > > #if __WORDSIZE == 64 \ > > > > || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > > > > # define __timespec64 timespec > > > > #else > > > > > > No. __timespec64 should be defined to timespec whenever __TIMESIZE > > > == 64. The timespec to which it is defined, in the public header, > > > would gain padding. > > > > > > The condition > > > > > > #if __WORDSIZE == 64 \ > > > || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > > > > > > is correct as a condition for struct timespec (in the public > > > header) *not* to have padding. > > > > Are you going to incorporate this into your series Lukasz? > > > > I currently have this diff which fixes the build failures for me: > > > > diff --git a/include/time.h b/include/time.h > > index 7ed3aa61d1d..91f6280eb4d 100644 > > --- a/include/time.h > > +++ b/include/time.h > > @@ -50,8 +50,7 @@ extern void __tzset_parse_tz (const char *tz) > > attribute_hidden; > > extern void __tz_compute (__time64_t timer, struct tm *tm, int > > use_localtime) __THROW attribute_hidden; > > > > -#if __WORDSIZE == 64 \ > > - || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > > +#if __TIMESIZE == 64 > > I've prepared v8 of __clock_settime64 conversion patches with the above > change: > https://patchwork.ozlabs.org/cover/1164209/ > > I've tested it with meta-y2038: > https://github.com/lmajewski/meta-y2038 > > as well as > ../src/scripts/build-many-glibcs.py > > It seems to work as expected. > > > # define __timespec64 timespec > > #else > > /* The glibc Y2038-proof struct __timespec64 structure for a time > > value. diff --git a/time/bits/types/struct_timespec.h > > b/time/bits/types/struct_timespec.h > > index 5b77c52b4f0..48405c4f08a 100644 > > --- a/time/bits/types/struct_timespec.h > > +++ b/time/bits/types/struct_timespec.h > > @@ -3,13 +3,25 @@ > > #define _STRUCT_TIMESPEC 1 > > > > #include <bits/types.h> > > +#include <endian.h> > > > > /* POSIX.1b structure for a time value. This is like a `struct > > timeval' but has nanoseconds instead of microseconds. */ > > struct timespec > > { > > __time_t tv_sec; /* Seconds. */ > > +#if __WORDSIZE == 64 \ > > + || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > > __syscall_slong_t tv_nsec; /* Nanoseconds. */ > > +#else > > +# if BYTE_ORDER == BIG_ENDIAN > > + __int32_t tv_pad; /* Padding */ > > + __syscall_slong_t tv_nsec; /* Nanoseconds */ > > +# else > > + __int32_t tv_nsec; /* Nanoseconds */ > > + __syscall_slong_t tv_pad; /* Padding */ > > +# endif > > +#endif > > }; > > I did not incorporated the above change to v8 of __clock_settime64 as > there are some issues raised by Joseph. That's fine, I can fix up his comments and include that in my series. > > Last but not least - we can get away with the above change as the > implicit padding works for RV32, and ARM32 (which both are LE). RV32 is actually both BE and LE. The spec allows it to be either. At the moment there are only LE implementations, but we should try to handle both. Alistair > > > > > #endif > > > > As well as that the timeval struct has the same issue. I'll have to > > look into that and see what the solution is there. > > > > Alistair > > > > > > > > -- > > > Joseph S. Myers > > > joseph@codesourcery.com > > > > > Best regards, > > Lukasz Majewski > > -- > > DENX Software Engineering GmbH, Managing Director: Wolfgang Denk > HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany > Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
Hi Alistair, > On Wed, Sep 18, 2019 at 2:28 PM Lukasz Majewski <lukma@denx.de> wrote: > > > > Hi Alistair, > > > > > On Tue, Sep 17, 2019 at 9:51 AM Joseph Myers > > > <joseph@codesourcery.com> wrote: > > > > > > > > On Tue, 17 Sep 2019, Lukasz Majewski wrote: > > > > > > > > > - New 32 bits glibc ports (like RISC-V 32) will get > > > > > __TIMESIZE == 64 (__WORDSIZE == 32) and no need to define the > > > > > -D_TIME_BITS=64 during the compilation. They will just get 64 > > > > > bit time API support from the outset. > > > > > > > > Yes, at least if such ports wish to use 64-bit time; I don't > > > > think we've really discussed if we want to *require* 64-bit > > > > time for future ports (e.g. the next revised resubmissions of > > > > the ARC and NDS32 ports). Certainly the work required right now > > > > for ARC or NDS32 to use 64-bit time would be significantly more > > > > than the work for RV32 (because they also support older kernel > > > > versions without the 64-bit-time syscalls, so all the Y2038 > > > > work for fallback at runtime to older syscalls becomes > > > > relevant), unless they decide on 5.1 or later as minimum kernel > > > > version. > > > > > - Already supported 32 bits architectures (like armv7-a with > > > > > __WORDSIZE == 32) will keep __TIMESIZE == 32 and require > > > > > -D_TIME_BITS=64 for compilation. > > > > > > > > Yes. > > > > > > > > > After glibc sets the minimal supported kernel version to 5.1 > > > > > and all conversions for syscalls to support 64 bit time API > > > > > are done the __TIMESIZE will be set to 64 and -D_TIME_BITS=64 > > > > > will not be required anymore for compilation. > > > > > > > > No. __TIMESIZE means the size of time_t in the unsuffixed ABIs > > > > in glibc, not the _TIME_BITS-dependent size of time_t in the > > > > current compilation. We hope in future to make _TIME_BITS=64 > > > > the default and only API supported for new compilations (which > > > > is independent of what the minimum kernel version is), but > > > > __TIMESIZE would still be 32, because the unsuffixed ABIs would > > > > remain compatible with existing binaries using 32-bit time. > > > > > Ok. So then we shall keep the condition: > > > > > > > > > > #if __WORDSIZE == 64 \ > > > > > || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > > > > > # define __timespec64 timespec > > > > > #else > > > > > > > > No. __timespec64 should be defined to timespec whenever > > > > __TIMESIZE == 64. The timespec to which it is defined, in the > > > > public header, would gain padding. > > > > > > > > The condition > > > > > > > > #if __WORDSIZE == 64 \ > > > > || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > > > > > > > > is correct as a condition for struct timespec (in the public > > > > header) *not* to have padding. > > > > > > Are you going to incorporate this into your series Lukasz? > > > > > > I currently have this diff which fixes the build failures for me: > > > > > > diff --git a/include/time.h b/include/time.h > > > index 7ed3aa61d1d..91f6280eb4d 100644 > > > --- a/include/time.h > > > +++ b/include/time.h > > > @@ -50,8 +50,7 @@ extern void __tzset_parse_tz (const char *tz) > > > attribute_hidden; > > > extern void __tz_compute (__time64_t timer, struct tm *tm, int > > > use_localtime) __THROW attribute_hidden; > > > > > > -#if __WORDSIZE == 64 \ > > > - || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > > > +#if __TIMESIZE == 64 > > > > I've prepared v8 of __clock_settime64 conversion patches with the > > above change: > > https://patchwork.ozlabs.org/cover/1164209/ > > > > I've tested it with meta-y2038: > > https://github.com/lmajewski/meta-y2038 > > > > as well as > > ../src/scripts/build-many-glibcs.py > > > > It seems to work as expected. > > > > > # define __timespec64 timespec > > > #else > > > /* The glibc Y2038-proof struct __timespec64 structure for a time > > > value. diff --git a/time/bits/types/struct_timespec.h > > > b/time/bits/types/struct_timespec.h > > > index 5b77c52b4f0..48405c4f08a 100644 > > > --- a/time/bits/types/struct_timespec.h > > > +++ b/time/bits/types/struct_timespec.h > > > @@ -3,13 +3,25 @@ > > > #define _STRUCT_TIMESPEC 1 > > > > > > #include <bits/types.h> > > > +#include <endian.h> > > > > > > /* POSIX.1b structure for a time value. This is like a `struct > > > timeval' but has nanoseconds instead of microseconds. */ > > > struct timespec > > > { > > > __time_t tv_sec; /* Seconds. */ > > > +#if __WORDSIZE == 64 \ > > > + || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > > > __syscall_slong_t tv_nsec; /* Nanoseconds. */ > > > +#else > > > +# if BYTE_ORDER == BIG_ENDIAN > > > + __int32_t tv_pad; /* Padding */ > > > + __syscall_slong_t tv_nsec; /* Nanoseconds */ > > > +# else > > > + __int32_t tv_nsec; /* Nanoseconds */ > > > + __syscall_slong_t tv_pad; /* Padding */ > > > +# endif > > > +#endif > > > }; > > > > I did not incorporated the above change to v8 of __clock_settime64 > > as there are some issues raised by Joseph. > > That's fine, I can fix up his comments and include that in my series. > > > > > Last but not least - we can get away with the above change as the > > implicit padding works for RV32, and ARM32 (which both are LE). > > RV32 is actually both BE and LE. The spec allows it to be either. Ok. I was not aware of this - and blindly assumed that it is LE. > At > the moment there are only LE implementations, but we should try to > handle both. Ok. Then if you don't mind, please add the above change to your series. > > Alistair > > > > > > > > > #endif > > > > > > As well as that the timeval struct has the same issue. I'll have > > > to look into that and see what the solution is there. > > > > > > Alistair > > > > > > > > > > > -- > > > > Joseph S. Myers > > > > joseph@codesourcery.com > > > > > > > > > > Best regards, > > > > Lukasz Majewski > > > > -- > > > > DENX Software Engineering GmbH, Managing Director: Wolfgang > > Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, > > Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: > > lukma@denx.de Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On Wed, Sep 18, 2019 at 10:25 AM Joseph Myers <joseph@codesourcery.com> wrote: > > On Wed, 18 Sep 2019, Alistair Francis wrote: > > > +#include <endian.h> > > > > /* POSIX.1b structure for a time value. This is like a `struct timeval' but > > has nanoseconds instead of microseconds. */ > > struct timespec > > { > > __time_t tv_sec; /* Seconds. */ > > +#if __WORDSIZE == 64 \ > > + || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) > > __syscall_slong_t tv_nsec; /* Nanoseconds. */ > > +#else > > +# if BYTE_ORDER == BIG_ENDIAN > > + __int32_t tv_pad; /* Padding */ > > + __syscall_slong_t tv_nsec; /* Nanoseconds */ > > +# else > > + __int32_t tv_nsec; /* Nanoseconds */ > > + __syscall_slong_t tv_pad; /* Padding */ > > +# endif > > +#endif > > The padding must be an *unnamed bit-field* so that { tv_sec, tv_nsec } > initializers (common in practice even if not officially supported by the > standards) continue to work. Also, I think you should just use "long int" > for tv_nsec in the case where there is padding, as the standard-defined > type (and then the padding can be "int: 32", so avoiding any dependence on > whether compilers support non-int bit-fields). Certainly the choice of > types for tv_nsec and padding should not depend on the endianness (the > patch above is using __int32_t for the first field and __syscall_slong_t > for the second, regardless of which is tv_nsec and which is padding). Ok, I have fixed this up. > > There are namespace issues when changing installed headers. You can't use > macros such as BYTE_ORDER or BIG_ENDIAN because they aren't in the > standard-reserved namespaces. > > Unfortunately the definitions of __LITTLE_ENDIAN and __BIG_ENDIAN are in > <endian.h> (__BYTE_ORDER is in the architecture-specific <bits/endian.h>), > and while the non-reserved names therein are all conditional on > __USE_MISC, I don't think we really want to start exporting them from > every header that uses struct timespec. My inclination would be to have a > separate bits/ header that only defines the __LITTLE_ENDIAN / __BIG_ENDIAN > / __PDP_ENDIAN macros (or that defines those and includes the > architecture-specific header for __BYTE_ORDER), so that other headers can > test endianness without bringing in all the other __USE_MISC > endian-related macros from <endian.h>, but Zack might advise on how such > changes would fit into his header cleanups. I think I understand what you mean, but it seems strange. I'm going to send an RFC patch and we can discuss there. Alistair > > -- > Joseph S. Myers > joseph@codesourcery.com
diff --git a/include/time.h b/include/time.h index 7ed3aa61d1d..91f6280eb4d 100644 --- a/include/time.h +++ b/include/time.h @@ -50,8 +50,7 @@ extern void __tzset_parse_tz (const char *tz) attribute_hidden; extern void __tz_compute (__time64_t timer, struct tm *tm, int use_localtime) __THROW attribute_hidden; -#if __WORDSIZE == 64 \ - || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) +#if __TIMESIZE == 64 # define __timespec64 timespec #else /* The glibc Y2038-proof struct __timespec64 structure for a time value. diff --git a/time/bits/types/struct_timespec.h b/time/bits/types/struct_timespec.h index 5b77c52b4f0..48405c4f08a 100644 --- a/time/bits/types/struct_timespec.h +++ b/time/bits/types/struct_timespec.h @@ -3,13 +3,25 @@ #define _STRUCT_TIMESPEC 1 #include <bits/types.h> +#include <endian.h> /* POSIX.1b structure for a time value. This is like a `struct timeval' but has nanoseconds instead of microseconds. */ struct timespec { __time_t tv_sec; /* Seconds. */ +#if __WORDSIZE == 64 \ + || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) __syscall_slong_t tv_nsec; /* Nanoseconds. */ +#else +# if BYTE_ORDER == BIG_ENDIAN + __int32_t tv_pad; /* Padding */ + __syscall_slong_t tv_nsec; /* Nanoseconds */ +# else + __int32_t tv_nsec; /* Nanoseconds */ + __syscall_slong_t tv_pad; /* Padding */ +# endif +#endif }; #endif