Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a timespec have more than 1 seconds worth of nanoseconds in the tv_nsec field?

Tags:

c

linux

time

Im working with the clock_gettime() command and trying to append a given amount of milliseconds to the timespec that I get from it. Can I just do this?

//milli is an int that can be any number (within reason)
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_nesc += (milli*1000000);

or do I need to split it up and find out if there are any whole seconds first, add those to the tv_sec field, and then add the remaining to the tv_nsec?

Essentially, can the tv_nsec field store more than 1 seconds worth of nanoseconds?

like image 960
Nealon Avatar asked Jun 14 '13 17:06

Nealon


2 Answers

It depends entirely on what you're going to do with it.

The tv_nsec members of a struct timespec is of type long. You can set it to any value you like in the range LONG_MIN to LONG_MAX. If you perform a calculation that exceeds LONG_MAX, which is at least 231-1, then you're going to have problems (undefined behavior that will probably show up as the value wrapping around).

Whether setting it to a value less than 0, or greater than or equal to one billion, will cause a problem depends on what you do with it. If you just want to print it, or perform some calculations on it, any valid long value should be ok -- but the stored values are probably more useful if you normalize them.

clock_gettime() should always give you a tv_nsec value in the range 0..999999999.

POSIX requires the clock_settime(), clock_nanosleep(), and nanosleep() functions to fail, and set errno to EINVAL, if "The tp argument specified a nanosecond value less than zero or greater than or equal to 1000 million."

References:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_settime.html http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_nanosleep.html http://pubs.opengroup.org/onlinepubs/9699919799/functions/nanosleep.html

like image 121
Keith Thompson Avatar answered Oct 22 '22 15:10

Keith Thompson


A tv_nsec field will tolerate a limited amount of nanosecond overflow (always enough to add two valid timespec nanosecond values, so, 999999999 + 999999999 = 1999999998). There is no guarantee that an arbitrary amount of overflow will work, though: on implementations with 32-bit long, you can only go up to just over two seconds' worth of nanoseconds, to 2.147483647 seconds. So if someone tells you to add 2500 milliseconds (2.5 seconds), that would overflow.

Edit to add: and, as Keith Thompson notes, you need to re-normalize after adding one timespec to another.

like image 1
torek Avatar answered Oct 22 '22 14:10

torek