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)