When invoking clock_gettime() may the returned tv_nsec field actually exceed a second?

According to opengroup

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.

So according to opengroup, it looks official that it must be less than 1 second.


I am fairly certain the answer is always going to be "no".

clock_gettime won't return with tv_nsec >= 10e9. clock_settime() and clock_nanosleep() both place this restriction on their inputs, so I've always assumed clock_gettime was consistent with that.

Also on Linux + glibc, if you dig deep enough into glibc, you'll see code like this:

Excerpt from glibc/nptl/pthread_clock_gettime.c:

/* Compute the seconds.  */
tp->tv_sec = tsc / freq;

/* And the nanoseconds.  This computation should be stable until
   we get machines with about 16GHz frequency.  */
tp->tv_nsec = ((tsc % freq) * 1000000000ull) / freq;

This also occurs in glibc/sysdeps/unix/clock_gettime.c.

But you're right, the man pages don't say. At least not what's in my Linux distro or on opengroup.org. So implementation is technically subject to change w/o warning.

If you're writing for Linux + glibc, I'd say your safe. You can check alternate open source libc libraries yourself, e.g. Android's bionic, or the scaled down newlib.

If you're targeting some other closed source POSIX system, you or your client are problem paying for support, so ask the vendor if it's not documented.

If trying to be portable as possible and feeling paranoid, wrap clock_gettime with a "normalizing" function like this:

int my_gettime( struct timespec * ts ) 
{  
   int ret; 
   if( 0 == (ret = clock_gettime(SOME_CLOCK, ts))
   {
      while (tv_nsec >= 1000000000 )
      {
         ts->tv_nsec -= 1000000000;
         ts->tv_sec += 1;
      }
   }
   return ret;
}

Tags:

Linux

C

Glibc

Libc