LWN.net Logo

Monotonicity of gettimeofday()

Monotonicity of gettimeofday()

Posted Feb 20, 2003 20:06 UTC (Thu) by im14u2c (subscriber, #5246)
In reply to: Monotonicity of gettimeofday() by zooko
Parent article: Kernel release status

If you want gettimeofday() to be non-decreasing, simply set your time once at bootup and don't run NTP or any other time adjustment daemon. The only thing that can make it non-monotonic is settimeofday().

The alternative is not that expensive. Here's an implementation off the top of my head that is monotonic non-decreasing for up to LONG_MAX seconds, so long as there aren't any shifts of time on the order of LONG_MAX/2:

void nondecreasing_gettimeofday(struct timeval *tv)
{
    static int first = 1;
    static struct timeval tv_adj, tv_prev;

    /* set our initial adjustment factor to 'now' so time starts at 0 */
    if (first)
    {
         gettimeofday(&tv_adj, NULL);
         first = 0;
    }

    gettimeofday(tv, NULL);

    tv->tv_sec  -= tv_adj.tv_sec;
    tv->tv_usec -= tv_adj.tv_usec;
    while (tv->tv_usec < 0) 
    { 
        tv->tv_sec--; 
        tv->tv_usec += 10000000; 
    }

    /* did time go backwards?  If so, make time sit still this time,
       and change our adjustment factor so we still see forward deltas. */
    if (tv->tv_sec < tv_prev.tv_sec ||
        (tv->tv_sec == tv_prev.tv_sec && 
         tv->tv_usec < tv_prev.tv_usec))
    {
        tv_adj.tv_sec  += tv_prev.tv_sec  - tv->tv_sec;
        tv_adj.tv_usec += tv_prev.tv_usec - tv->tv_usec;
        *tv = tv_prev;
    } else /* time went forward or stayed put, so remember it. */
    {
        tv_prev = *tv;
    }
}

I agree, it's not perfect. And it certainly has a touch of "good enough is the worst enemy of best." But I feel it's perfectly serviceable.


(Log in to post comments)

Monotonicity of gettimeofday()

Posted Feb 20, 2003 20:09 UTC (Thu) by im14u2c (subscriber, #5246) [Link]

Oh, and you're right that you need to use the filesystem to get monotonicity across apps if they share timebases. That kinda sucks.

Bear in mind, though, that that's only a problem on systems that are running a time daemon that allows large time deltas. I think xntpd can be configured to avoid those, and the kernel mechanisms for adjtimex do support non-decreasing monotonic clocks.

Copyright © 2008, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds