[m-rev.] time additions (was Re: for review: Add random.init/3)

Paul Bone paul at bone.id.au
Thu May 26 11:52:04 AEST 2016


On Thu, May 26, 2016 at 11:25:16AM +1000, Peter Wang wrote:
> On Wed, 25 May 2016 16:28:32 +1000, Peter Wang <novalazy at gmail.com> wrote:
> > On Wed, 25 May 2016 15:55:50 +1000, Paul Bone <paul at bone.id.au> wrote:
> > > For review by anyone
> > > 
> > > ----
> > > 
> > > Add random.init/3
> > > 
> > > random.init/3 makes it easier to seed the random number generator.  It will
> > > calculate a seed based on the current time and, if known, the process ID.
> > > This is sufficient for simple applications but shouldn't be used for
> > > security-sensitive applications.
> 
> A common way to seed the PRNG in C is
> 
>     srand(time(0));
> 
> The time in seconds-since-the-Unix-epoch is useful for many other
> purposes, in addition to seeding any PRNG implementation.
> 
> I would like to see an easy way to get an integer (simple)
> representation of Unix time, as well as a way to convert between an
> integer representation and the time_t values.
> 
> The main problem is probably that a signed 32-bit int cannot represent
> Unix times past some time in 2038.  Apart from 32-bit machines, this
> problem also affects C# and Java backends.
> 
> difftime/2 returns a float.  You can get the current unix time as a
> float with
> 
>     time(Now, !IO),
>     Secs = difftime(Now, unix_epoch)
> 
> where `unix_epoch' returns a time_t.
> 
> Using floats is not very satisfying but in most cases they will be
> double precision, and capable of representing any reasonable time
> value precisely.
> 
> Here are some suggested additions to time.m
> 
>     :- func unix_epoch = time_t.
> 
>     :- pred seconds_since_unix_epoch(float::out, io::di, io::uo) is det.
> 
>     :- func seconds_since_unix_epoch(time_t) = float.
> 
>     :- func from_seconds_since_unix_epoch(float) = time_t.
> 
> Thoughts?

Eww,

My reaction to the use of floats for this kind of thing is rater visceral.

I agree that it may be useful to expose time in seconds since the epoch for
other reasons.  And as an aside, gettimeofday() could be useful if portable
too.

I think there are a few potential solutions.

  1 Use an int and hope for the best for 32-bit C / Java and C# platforms.
    Maybe the world will end before 2038 and we'll also never need to store
    a date then or after, or if we do, just use 64-bit C.  While this isn't
    a great solution I'm being partly serious, because I think it's better
    than using floats.  Floats *shudder*.

  2 Same as #1, but we also update the Java / C# backends to use 64bit
    integers.  AFAIK these need to be boxed in many places anyway, so I
    can't imagine this having any additional penalty.

  3 Don't expose seconds since epoch, instead add a predicate to random.m
    which takes a time_t and seeds the PRNG from that.  We could either 
    abusing our knowledge of the underlying representation of time_t or
    create a hidden interface in time.m to expose something to read the
    seconds-since-epoch.


-- 
Paul Bone


More information about the reviews mailing list