Bug 78537 - times(2) not functioning per the Posix spec
Summary: times(2) not functioning per the Posix spec
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: standards (show other bugs)
Version: Unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-standards (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-03-07 15:50 UTC by Matthew Soffen
Modified: 2017-12-31 22:23 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Matthew Soffen 2005-03-07 15:50:06 UTC
This is a finding from the Linux-Ha project and Robert Watson agrees that it does appear to be a bug in the behavior.

According to the posix spec, the times (2) structure is supposed be unchangable from boot to boot.  It  is affected by any clock changes and per the spec ( http://www.opengroup.org/onlinepubs/009695399/functions/times.html ) it shouldn't be.

Fix: 

Make times(2) work like the posix spec.  It shouldn't be based on Epoch being 0, it should be based on "startup" time being the 0 time.
How-To-Repeat: Have something using  a times(2) structure to generate unique ID ( for the current run), cange the system time and you would be able to create duplicate time structurs.
Comment 1 Robert Watson freebsd_committer freebsd_triage 2005-03-07 16:10:08 UTC
Responsible Changed
From-To: freebsd-bugs->phk

Chown to phk, as he was involved in the discussion at LinuxForum.dk and 
is interested in taking a look at this.
Comment 2 Bruce Evans 2005-03-07 21:21:01 UTC
On Mon, 7 Mar 2005, Matthew Soffen wrote:

>> Description:
> This is a finding from the Linux-Ha project and Robert Watson agrees that it does appear to be a bug in the behavior.
>
> According to the posix spec, the times (2) structure is supposed be unchangable from boot to boot.  It  is affected by any clock changes and per the spec ( http://www.opengroup.org/onlinepubs/009695399/functions/times.html ) it shouldn't be.

Please limit line lengths to considerably less than 241 characters.

I think you mean uniqueness of the returned value, not "unchangable
from boot to boot" of the struct contents or the returned value.  POSIX
doesn't require any of these.  It explicitly allows overflow of the
returned value and implictly allows overflow of the struct contents, as
in must since this interface is broken as designed and overflow occurs
on most systems.

>> How-To-Repeat:
> Have something using  a times(2) structure to generate unique ID ( for the current run), cange the system time and you would be able to create duplicate time structurs.

times(2) cannot be used to generate unique ids, for many reasons:
1. The return value might overflow.  It overflows in practice every 388+
    days under FreeBSD.
2. The return value shouldn't be, but is under FreeBSD, non-monotonically
    increasing.  This might be the bug that you mean.  The return value
    should track a monotonic clock, one that is actually useful like
    CLOCK_MONOTONIC, but it actually tracks CLOCK_REALTIME.  This is not
    a serious bug.  Much more than times(2) breaks if CLOCK_REALTIME is
    allowed to to go backwards.
3. The return value might be non-strictly monotonic.  Since the resolution
    of clock_t is too small to be useful for almost everything (still 1/128
    seconds despite hat resolution being too small to be useful 10+ years
    ago when meachines were 1000+ times slower), the return vaue of times(2)
    is very likely to be the same for successive calls.
4. The return value might be non-unique across processes, even on non-SMP
    systems with processes making strictly ordered calls to times(), since
    POSIX permits even the return value to be relative to the start of the
    process so as to reduce the overflow possibilities for the return value.
5. The values in the struct might overflow.  Under FreeBSD, this can happen
    after 388+ days for a process using 100% of the CPU.
6. The values in the struct might be non-monotically increasing.  This isn't
    a problem under FreeBSD, but was on old versions until 1999/03/13.
7. The values in the struct might be non-strictly monotonic.  This is the
    usual case in FreeBSD, as in (3).
8. The values in the struct might are non-unique across processes.

>> Fix:
> Make times(2) work like the posix spec.  It shouldn't be based on Epoch being 0, it should be based on "startup" time being the 0 time.

Basing it on the Epoch is not a problem, since overflow of clock_t is
benign and the resulting timestamps are no less usable than ones based
on a more recent starting point (in fact, they are more usable since
you can determine the amount lost to overflow using a non-broken interface).
POSIX doesn't require any particular starting point.  As mentioned in (4),
POSIX even allows using the start of the process for the starting point.

Basing it on the Epoch is harder to implement since we only have monotonic
times relative to system boot.

Bruce
Comment 3 Poul-Henning Kamp 2005-03-07 21:26:50 UTC
In message <20050308072635.G42370@delplex.bde.org>, Bruce Evans writes:

>2. The return value shouldn't be, but is under FreeBSD, non-monotonically
>    increasing.  This might be the bug that you mean.  The return value
>    should track a monotonic clock, one that is actually useful like
>    CLOCK_MONOTONIC, but it actually tracks CLOCK_REALTIME.  This is not
>    a serious bug.  Much more than times(2) breaks if CLOCK_REALTIME is
>    allowed to to go backwards.

This is actually the item we talked about.

I will fix this to use CLOCK_MONOTONIC.

And yes, we should fix all the things that don't like CLOCK_REALTIME
to reflect realtime.

>3. The return value might be non-strictly monotonic.  Since the resolution
>    of clock_t is too small to be useful for almost everything (still 1/128
>    seconds despite hat resolution being too small to be useful 10+ years
>    ago when meachines were 1000+ times slower), the return vaue of times(2)
>    is very likely to be the same for successive calls.

I think one would be forced to do modulus-2 circular arithmetic like
on sequence numbers in various protocols.

Isn't there a standards requirement for the resolution to be 1000000
these days ?  (See tail end of clock(3) manual page).

>4. The return value might be non-unique across processes, even on non-SMP
>    systems with processes making strictly ordered calls to times(), since
>    POSIX permits even the return value to be relative to the start of the
>    process so as to reduce the overflow possibilities for the return value.

I don't think we want to go that way.

-- 
Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
phk@FreeBSD.ORG         | TCP/IP since RFC 956
FreeBSD committer       | BSD since 4.3-tahoe    
Never attribute to malice what can adequately be explained by incompetence.
Comment 4 Bruce Evans 2005-03-07 23:05:29 UTC
On Mon, 7 Mar 2005, Poul-Henning Kamp wrote:

> In message <20050308072635.G42370@delplex.bde.org>, Bruce Evans writes:

>> 3. The return value might be non-strictly monotonic.  Since the resolution
>>    of clock_t is too small to be useful for almost everything (still 1/128
>>    seconds despite hat resolution being too small to be useful 10+ years
>>    ago when meachines were 1000+ times slower), the return vaue of times(2)
>>    is very likely to be the same for successive calls.
>
> I think one would be forced to do modulus-2 circular arithmetic like
> on sequence numbers in various protocols.

Do you mean that with a resoultion large enough to give strict monotonicity,
wraparound would be much more likely and complications to handle it would
be essential?

> Isn't there a standards requirement for the resolution to be 1000000
> these days ?  (See tail end of clock(3) manual page).

clock(3) documents a requirement for CLOCKS_PER_SEC to be precisely
1000000 in some standards.  This is a bug in these standards.  clock(3)
mentions SUSv2 and POSIX but isn't very clear about the latter.  The
current POSIX standard makes it clear that this bug is only in the XSI
extension.

Anyway, this doesn't affect times() since the units for times() are
sysconf(_SC_CLK_TCK), not CLOCKS_PER_SEC.

FreeBSD still hasn't caught up with POSIX's removal of the bogus interface
CLK_TCK.  FreeBSD's implementation of CLK_TCK as a compile-time constant
is one of 2 things that inhibit giving times() and friends enough
resolution for these interfaces to actually be useful.  The other one is:
- clock_t is 32-bits on all arches, so the resolution can't be high enough
   without breaking the range requirement.  IIRC, clock_t is supposed to
   have a range of at least 24 hours -- this limits sysconf(_SC_CLK_TCK)
   to <= 49710, so in particular it can't equal CLOCKS_PER_SEC on XSI
   systems with 32-bit clock_t's.

CLK_TCK is also a problem for emulators.  In the Linux emulator, times()
is in the kernel and it has the same code and thus bugs as the library
version except:
- it already uses a monotonic clock (microuptime())
- it has different too-small values for CLK_TCK (100 for i386's and 1024
   on alphas)
- FreeBSD can't fix it until Linux does.

Bruce
Comment 5 alanr 2005-03-08 18:12:01 UTC
Wraparound is not particularly a problem for us.

Traditionally, the value of sysconf(_SC_CLK_TCK) is something like 60-1024.

Anything in this rough range works quite nicely.  1024 is probably best.

For our purposes, anything much larger than 1000 isn't helpful to us.  Note 
that anyone using this POSIX call in a portable way would not expect high 
resolution from it, because it's traditionally not a high-res way to get 
the time.  If they want to be non-portable, your other calls work nicely 
for a high-resolution answer.

We're trying to set timeouts for events, and millisecond resolution is more 
than adequate.

It is NOT necessary for each successive call to have a different value. 
The POSIX spec doesn't suggest that, nor does any existing implementation 
do that.


-- 
     Alan Robertson <alanr@unix.sh>

"Openness is the foundation and preservative of friendship...  Let me claim 
from you at all times your undisguised opinions." - William Wilberforce
Comment 6 Eitan Adler freebsd_committer freebsd_triage 2011-09-24 18:44:21 UTC
Responsible Changed
From-To: phk->freebsd-bugs

return to the pool (approved by phk)
Comment 7 Mark Linimon freebsd_committer freebsd_triage 2014-04-20 23:22:55 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-standards

Canonicalize assignment.
Comment 8 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 07:58:58 UTC
For bugs matching the following criteria:

Status: In Progress Changed: (is less than) 2014-06-01

Reset to default assignee and clear in-progress tags.

Mail being skipped