Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

meaning of tv_nsec

890 views
Skip to first unread message

viza

unread,
Aug 8, 2008, 4:12:12 PM8/8/08
to
Hi

Does the tv_nsec member of struct timespec mean nanoseconds after the
time given by the time tv_sec member, or further from zero than that
member?

ie, does (struct timespec){ .tv_sec= -2, .tv_nsec= 250000000 } mean two
and a quarter seconds ago (or before the epoch) or does it mean one and
three quarters (-2 seconds + 250000000 nanoseconds)?

Where is this defined? I can't find it anywhere in SUSv3 or manpages
from Linux/glibc or OpenBSD.

Does the same apply to tv_usec in struct timeval?

Thanks
viza

Ian Collins

unread,
Aug 8, 2008, 5:15:57 PM8/8/08
to
viza wrote:
> Hi
>
> Does the tv_nsec member of struct timespec mean nanoseconds after the
> time given by the time tv_sec member, or further from zero than that
> member?
>
> ie, does (struct timespec){ .tv_sec= -2, .tv_nsec= 250000000 } mean two
> and a quarter seconds ago (or before the epoch) or does it mean one and
> three quarters (-2 seconds + 250000000 nanoseconds)?
>
Both tv_sec and tv_nsec are signed values. tv_sec*oneBillion+tv_nsec is
the effective value in nS of a timespec.

> Where is this defined? I can't find it anywhere in SUSv3 or manpages
> from Linux/glibc or OpenBSD.
>

Try man time.h.

> Does the same apply to tv_usec in struct timeval?
>

The members of a timeval are also signed.

--
Ian Collins.

Harold Shand

unread,
Aug 8, 2008, 6:28:09 PM8/8/08
to

I (who am not the OP) have just read this and the related SUS document
from which it appears to be cribbed and there is no discussion about how
to treat a negative value. Yes, the types are clearly signed but where
is the documentation which backs up your assertion that
"tv_sec*oneBillion+tv_nsec is the effective value in nS of a timespec"?

HS

Ian Collins

unread,
Aug 8, 2008, 6:38:38 PM8/8/08
to
Harold Shand wrote:
>
> I (who am not the OP) have just read this and the related SUS document
> from which it appears to be cribbed and there is no discussion about how
> to treat a negative value. Yes, the types are clearly signed but where
> is the documentation which backs up your assertion that
> "tv_sec*oneBillion+tv_nsec is the effective value in nS of a timespec"?
>
It probably isn't documented because negative times are meaningless to
the functions that use timespec. Passing a nanosecond value less than
zero or greater than or equal to 10^9 is an error (at least for nanosleap).

I guess my interpretation comes from years of using timespec objects for
time differences and intervals in C++ where I use that equation to
convert timespec to int64_t.

--
Ian Collins.

viza

unread,
Aug 8, 2008, 6:50:37 PM8/8/08
to
Hi,

On Sat, 09 Aug 2008 09:15:57 +1200, Ian Collins wrote:
> viza wrote:

>> Does the tv_nsec member of struct timespec mean nanoseconds after the
>> time given by the time tv_sec member, or further from zero than that
>> member?

> Both tv_sec and tv_nsec are signed values. tv_sec*oneBillion+tv_nsec is


> the effective value in nS of a timespec.

tv_nsec is of signed type, but eg: man clock_nanosleep states that it
cannot have a negative value, just the same as it cannot have a value
greater than 999999999.

suppose I wanted to wait until half a second before the epoch:

clock_nanosleep( CLOCK_REALTIME, TIMER_ABSTIME,
(struct timespec){ .tv_sec= 0, .tv_nsec= -500000000 }, NULL );

is required by the SUSv3 to return -1 with errno= EINVAL;

(This could just be a mistake in the standard - it isn't perfect)

on the other hand:

clock_nanosleep( CLOCK_REALTIME, TIMER_ABSTIME,
(struct timespec){ .tv_sec= -1, .tv_nsec= 500000000 }, NULL );

seems instinctively to refer to epoch -1.5 seconds. I suppose It must be
the case that it doesn't and it refers to -0.5 seconds, because otherwise
that time would simply be unaddressable.

The latter would agree with the obvious tv_sec+((long)1E9)*tv_nsec. But
I can't find it anywhere. Certainly SUSv3 leaves it ambiguous.

>> Where is this defined? I can't find it anywhere in SUSv3 or manpages
>> from Linux/glibc or OpenBSD.
>>
> Try man time.h.

Nothing helpful there on any system I can find.

It doesn't matter in practice I suppose, because I'm sure all sorts of
software breaks if you try to run it with the clock set to pre-1970.

David Schwartz

unread,
Aug 8, 2008, 6:59:58 PM8/8/08
to
On Aug 8, 1:12 pm, viza <tom.v...@gm-il.com.obviouschange.invalid>
wrote:

> Hi
>
> Does the tv_nsec member of struct timespec mean nanoseconds after the
> time given by the time tv_sec member, or further from zero than that
> member?
>
> ie, does (struct timespec){ .tv_sec= -2, .tv_nsec= 250000000 } mean two
> and a quarter seconds ago (or before the epoch) or does it mean one and
> three quarters (-2 seconds + 250000000 nanoseconds)?
>
> Where is this defined?  I can't find it anywhere in SUSv3 or manpages
> from Linux/glibc or OpenBSD.

http://www.opengroup.org/onlinepubs/007908799/xsh/realtime.html:
"The tv_nsec member is only valid if greater than or equal to zero,
and less than the number of nanoseconds in a second (1000 million).
The time interval described by this structure is (tv_sec * 10'-.4m'9'.
4m' + tv_nsec) nanoseconds. "

In any event, any other interpretation would be bizarre, to say the
least.

DS

viza

unread,
Aug 8, 2008, 7:12:39 PM8/8/08
to
On Fri, 08 Aug 2008 15:59:58 -0700, David Schwartz wrote:
> On Aug 8, 1:12 pm, viza wrote:

>> Does the tv_nsec member of struct timespec mean nanoseconds after the
>> time given by the time tv_sec member, or further from zero than that
>> member?

>> Where is this defined?

> http://www.opengroup.org/onlinepubs/007908799/xsh/realtime.html

I take back my quite incorrect slander of this explicit (if labyrinthine)
standard.

viza

Boon

unread,
Aug 9, 2008, 3:26:43 AM8/9/08
to
David Schwartz wrote:

> http://www.opengroup.org/onlinepubs/007908799/xsh/realtime.html
>
> "The tv_nsec member is only valid if greater than or equal to zero,
> and less than the number of nanoseconds in a second (1000 million).
> The time interval described by this structure is (tv_sec * 10'-.4m'9'.
> 4m' + tv_nsec) nanoseconds. "

Is 10'-.4m'9'.4m' supposed to mean 10^9?

Are '-.4m' and '.4m' tags for some markup language? Which one?

Måns Rullgård

unread,
Aug 9, 2008, 6:13:50 AM8/9/08
to
Boon <root@localhost> writes:

Good question. The web page contains that exact text. My guess is
the HTML has been generated from some other markup language using a
tool that didn't understand all directives. Guessing further, I
suspect those directives shift the baseline of the text up and down.

--
Måns Rullgård
ma...@mansr.com

phil-new...@ipal.net

unread,
Aug 13, 2008, 12:22:54 PM8/13/08
to
On Sat, 09 Aug 2008 10:38:38 +1200 Ian Collins <ian-...@hotmail.com> wrote:

| Harold Shand wrote:
|>
|> I (who am not the OP) have just read this and the related SUS document
|> from which it appears to be cribbed and there is no discussion about how
|> to treat a negative value. Yes, the types are clearly signed but where
|> is the documentation which backs up your assertion that
|> "tv_sec*oneBillion+tv_nsec is the effective value in nS of a timespec"?
|>
| It probably isn't documented because negative times are meaningless to
| the functions that use timespec. Passing a nanosecond value less than
| zero or greater than or equal to 10^9 is an error (at least for nanosleap).

Such values are not meaningless. The meaning is obvious to most humans.
However, the SUSv3 specification does say that if the nanosecond value is
less than 0 or greater than or equal to 1000000000 then nanosleep shall
return -1 with errno equal to EINVAL.


| I guess my interpretation comes from years of using timespec objects for
| time differences and intervals in C++ where I use that equation to
| convert timespec to int64_t.

I use the same equation without involving C++. When I convert a timespec
to a type equivalent to int64_t, I do _not_ check for validity. Thus if
the nanosecond part value were 2000000000 then it would result in big total
of nanoseconds being 2000000000 higher than if it were just 0 (e.g. it would
be as if the seconds part were 2 higher). Likewise if the nanosecond part
value were -2000000000 then it would be 2 seconds lower.

When I convert from a 64 bit big nanoseconds value to struct timespec, then
I do it like:
timespec.tv_sec = big_nanos / 1000000000;
timespec.tv_nsec = big_nanos % 1000000000;
and this will result in values for tv_nsec that nanosleep will accept. But
it is possible to have 64 bit values that cannot be correctly converted and
I sometimes check for this.

IMHO[0] we would have been better off using a 64-bit value, even if it were a
synthesized one on 32-bit machines, for the API parts that need microsecond
or nanosecond resolution. A signed 64-bit number used as nanoseconds using
the epoch of 1970-01-01 == 0 would cover a time span from 00:12:43.145224192
on Tuesday 21 September 1677 to 23:47:16.854775807 on Friday 11 April 2262.
That's well beyond 03:14:07 on Tuesday 19 January 2038.

IMHO[1] we should adopt a new API component that specifically uses this time
format (a single signed 64-bit integer giving a nanoseconds displacement from
the epoch) to interface to all time functions of the system. This would
include (with suggested function names):
time_ns()
sleep_ns()
getitimer_ns()
setitimer_ns()
ctime_ns() - the 2 argument version
gmtime_ns() - the 2 argument version
localtime_ns() - the 2 argument version

--
|WARNING: Due to extreme spam, googlegroups.com is blocked. Due to ignorance |
| by the abuse department, bellsouth.net is blocked. If you post to |
| Usenet from these places, find another Usenet provider ASAP. |
| Phil Howard KA9WGN (email for humans: first name in lower case at ipal.net) |

0 new messages