Subject: Re: Avoiding microtime(9) global state
To: Martin Husemann <>
From: Frederick Bruckman <>
List: tech-smp
Date: 06/30/2004 09:55:15
In article <>, (Martin Husemann) writes:
> The audit trail to pr/24207 has the start of a discussion that IMHO should
> be better here.

You'll look for that thread in vain, by the way, as the mails were sent to
"gnats-admin" and "kern-bug-people", and not "gnats-bugs" -- which is where
they'd need to go to be appended to a PR automatically.

> The problem, as Jason explained in that PR: microtime(9) traditionally
> promissed to never return the same values on successive calls, no matter
> what CPU the call runs on.
> This implies global (not only per CPU) state and aproppriate locking.
> Ntpd does not like this locking, but we can not keep the monotonic non
> repeating API promise without it.

I don't think "ntpd" is being bothered by the lock so much, especially
now that we're not reading the cycle counter until after taking the lock.
This produced an evident improvement on my SMP i386 boxes, and I got one
good report from an alpha user. (We're talking about cc_microtime() only.)

> We could, however, easily implement a very accurate mircotime_ng(9) [or
> whatever you'd like to call it] that does not do the locking, does not
> promise to deliver different values on successive calls, and still
> provides a very exact estimate of the time. If a process happens to
> switch CPUs between two calls it might even make time go slightly
> backward. We sync time between CPUs once every second, and cycle counter
> equipped CPUs should be able to provide consistent results in between,
> so for "normal" usage IMHO this variant of microtime should be enough.
> We could then, in a second step, sweep through the kernel and identify
> calls to microtime() that depend on the strong monotonic behaviour, and
> replace all others with calls to the new function.
> What do you think?

microtime()'s monoticity isn't that strong, as it can jump backwards if
the change is greater than one second. Presumably, all callers special
case for that. [Right...]

What does the "_ng" stand for? (no global? no good?)

I think it would be cleaner to simply drop the monoticity requirement
of microtime(), and create a microtime1() for any callers that really
need the old semantics.

Interestingly, sys_clock_gettime(CLOCK_REALTIME, ...) simply calls
microtime(), while sys_clock_gettime(CLOCK_MONOTIME, ...) uses absolute
"mono_time". [clock_gettime(CLOCK_REALTIME, ...) is the interface that
"ntpd" uses.] My reading of SUSv3, however, is that it supports no
guarantee of monoticity in CLOCK_REALTIME, but says that the
CLOCK_MONOTIME clock can have backwards jumps of a magnitude that
is implementation dependent -- i.e, MONO_TIME should be using current
microtime(), or proposed microtime1(), and CLOCK_REALTIME should be
using the new function.