[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 1/1] Y2038: add function __difftime64

From: Albert ARIBAUD
Subject: Re: [PATCH 1/1] Y2038: add function __difftime64
Date: Thu, 5 Jul 2018 20:36:37 +0200

Hello all,

On Wed, 27 Jun 2018 13:03:42 +0200, Albert ARIBAUD
<address@hidden> wrote :

> Hi Paul,
> On Mon, 25 Jun 2018 16:56:14 -0700, Paul Eggert <address@hidden>
> wrote :
> > On 06/25/2018 03:32 PM, Albert ARIBAUD wrote:  
> > > I replaced the original 32-bit difftime with a wrapper
> > > around the 64-bit time; and in both cases, there were two functions, on
> > > for each time size.    
> > 
> > Yes, and all this is in the patch you posted in 
> > <https://www.sourceware.org/ml/libc-alpha/2018-06/msg00605.html>. What 
> > I'm not understanding is how the functions it defines (__difftime64 and 
> > __difftime on 32-bit hosts, and just __difftime on 64-bit hosts) 
> > interoperate the with user-defined macro (is it still _TIME_BITS? I 
> > can't recall) that specifies whether the user wants time_t is 64 or 32 
> > bits, and how they interoperate with the macro that Joseph Myers 
> > suggested was needed by the system to say whether a 32-bit time_t 
> > variant is supported.
> > 
> > In short, I'm still missing the bigger picture here.  
> OK, so let me try to sum things up (I'll update the design document
> accordingly).
> Right now, on 32-bit architectures, application source code which uses
> glibc and manipulates time can only go as far as Y2038, because the
> public API declares only 32-bit types (time_t and related structures)
> and functions (difftime etc). Any time beyond Y2038 is undefined
> behavior  -- I've documented behaviors ranging from just time rollover
> (back to Dec. 1901 IIRC) to full system freeze.
> My goal is:
> - to make glibc provide, when _TIME_BITS is is defined equal to 64, the
>   same set of type and function names but with 64-bit time support (and
>   with _TIME_BITS undefined or defined equal to 32, glibc would stick
>   with the old types and functions);
> - to ensure that, at least for now, the existing ABI remain unchanged,
>   i.e. application modules resulting from compiling against current
>   glibc should link against a 64-bit-time-capable glibc and run
>   without errors.
> In other words, source code referring to difftime would result in
> object code referring either to the existing __difftime symbol if
> _TIME_BITS is not equal to 64, or to some new __difftime64 symbol if
> _TIME_BITS is equal to 64; and the symbol __difftime in glibc should
> always represent the existing 32-bit implementation so that existing,
> already compiled, client code would execute the difftime they expect
> to.
> How to achieve this:
> - since a single glibc header install must support compiling both
>   32-bit-time and new 64-bit-time object code, glibc must provide two
>   sets of public API symbol definitions, one for 32-bit-time, exposed
>   if _TIME_BITS is defined equal to 32 or undefined, and one for 64-bit
>   time, exposed if _TIME_BITS is defined equal to 64.
> - since a single glibc library must support both existing 32-bit-time
>   and new 64-bit-time object code, glibc must therefore provide two
>   sets of implementation symbols at the same time: the current set for
>   object client code which was compiled for 32-bit time, and a new set
>   for object client code which was compiled for64-bit time.
> Refining the how:
> - we cannot introduce the public API and _TIME_BITS support in small
>   batches, because if you switch time_t to 64-bit, that switches all
>   functions using time_t to 64-bit too, and all types using time_t as
>   well. Basically, _TIME_BITS and the switch of the API to 64-bit time
>   has to be a single, atomic, patch.
> - but we can introduce the new 64-bit symbols, including the
>   publically visible ones, even though we won't expose them as they
>   will be in the end. These new symbols do not need to be all introduced
>   in a single patch; this can be done progressively.
> For instance, in the end, we will have to map the public API's difftime
> symbol either to the existing 32-bit __difftime or to a new 64-bit
> __difftime64, depending on _TIME_BITS. So we will /have/ to provide a
> public symbol __difftime64. Only in the final _TIME_BITS patch will
> this symbol be aliased with 'difftime' -- for client code which compiles
> with _TIME_BITS=64.
> Further refining the how:
> - We can create 64-bit implementations from existing 32-bit ones, with
>   some hand-optimizing based on time_t assumptions which we know
>   always / never apply to __time64_t (such as possibly being integer or
>   being floating point) or size considerations (such as some precision
>   loss risks which might not apply to __time64_t).
> - We can/must rewrite some internals of glibc to handle __time64_t
>   rather than time_t.
> - Once there is a 64-bit implementation for a given functionality in
>   32-bit architectures, then the 32-bit implementation can be turned
>   into a wrapper around the 64-bit one (if the 32-bit implementation
>   is even needed; for 64-bit architectures and x32, it does not need
>   to be defined at all).
>   This is where we need another macro, __TIME_SIZE. While _TIME_BITS
>   tells us, at client code compile time, whether client code wants a
>   64-bit time API or not, __TIMESIZE tells us, at glibc compile time,
>   whether the time_t for the considered architecture is 64-bit or not.
>   Architectures with 64-bit time_t do not need 32-bit wrappers, and can
>   use time_t for their __time64_t; others need the 32-bit wrappers, and
>   need separate time_t and __time64_t.
> Final picture:
> - the set of patches to support Y2038 will consist in new types and new
>   functions (either visible from the public or purely internal to
>   glibc) or internal glibc function conversions to 64 bit; these
>   patches will have some of the implementation dependent on __TIMESIZE.
>   Then in the end a single patch will expose the 'old' or 'new' set
>   depending on _TIME_BITS. 
> Is this clear enough? Don't hesitate to ask for further clarifications.
> > > Since you want the changes in gnulib first, then I suspect I should
> > > provide branches above gnulib as well as above glibc? If so, what
> > > would you recommend as a good source on setting up a build and test
> > > setup for gnulib, similar to build-many-glibcs.py is for glibc?  
> > 
> > Yes, it would be helpful to have this in Gnulib too. The basic idea is 
> > that Gnulib and glibc sources should be as close to each other as 
> > possible; preferably identical. You can build and test a Gnulib module 
> > by running './gnulib-tool --test modulename'; run './gnulib-tool --help' 
> > for more.  
> Since gnulib is on Savannah, not Sourceware, I assume I will need to be
> given some level of write access to the Savannah gnulib repository in
> order to provide branches there too, similar to what is done in glibc.
> Who should I ask this?

Cross-posting this to both the glibc and gnulib lists for now; if anyone
thinks this thread should stay on only gnulib, feel free.

I have had a look at gnulib in the meantime, and I would like to know
if the following assumptions are correct:

- gnulib does not contain any module which provides the time_t type, but
  some of gnulib's modules assume there is such a type, and it might be
  wider than 32 bits.

- gnulib contains a year2038 module which is only intended to check
  whether time_t is limited to Y2038 or not.

- gnulib does not provide difftime either, so ATM a difftime patch
  would only make sense in glibc, not gnulib.

- gnulib makes no assumption on how it is used in object form; notably,
  it makes no assumption that it will be compiled into a shared object
  form which will provide the same functionalities for both 64-bit and
  32-bit callers.

Are all these correct, and if not, could someone develop in what
respect they aren't?


reply via email to

[Prev in Thread] Current Thread [Next in Thread]