> From: Mulyadi Santosa [mailto:[email protected]]
> IMO, if both are really fetching time from clock source like RTC, then
> it might take long..however, the reality in kernel code, AFAIK, it's
> not like that. It's more like jiffies plus ...I could say, "fuzzy
> factor". Jiffies itself, in turn, is updated only every 1/HZ seconds.
> This could be less when we use no_hz...
Hi Mulyadi,
What worries me is that sequence of calling gettimeofday() and then
time(), the value returned by gettimeofday() is in the future and in
front of time()'s return value by more than 1,000,000 microseconds. To
me this is unexpected, return value of time() should always equal tv_sec
value from gettimeofday(). Ok I know there is no spec that says that -
just what I would expect.
> > They both use the same timer (xtime) but gettimeofday() calls
> > getnstimeofday() which calls timespec_add_ns(), which can modify the
> > seconds portion of timespec struct. I dont understand why
> > getnstimeofday() uses a loop and then adds on nanoseconds to the
result?
>
> I can only provide some rough guess:
>
> as I said above, it adds some "fuzz factor". And IMO, this is not a
> random number. I dare to guess it's calculated time to time as a
> representation of clock difference (or shall I say, clock drift?)
> between one updated every 1/HZ and the real clock in RTC. AFAIK
> fetching time directly RTC is an expensive operation (meaning: needs
> many cpu cycles), thus it would be wiser to just use updated jiffies.
>
> As to why it needs to do it repeatedly? That I don't really know.
> Likely, it is done more than once since the time value we read might
> be a value that is updated "in flight". Thus, to be sure, we read
> multiple times. AFAIK seq lock is unblocking lock, thus to avoid
> contention over several reader that might need time read too.
>
> Hopefully I am offering logical explanation...all above are purely my
> interpretation based directly from code reading.
Ok so do I have this right (all function comments are mine)
213void getnstimeofday(struct timespec *ts)
214{
215 unsigned long seq;
216 s64 nsecs;
217
No idea on this line - guessing debug/diagnostic
218 WARN_ON(timekeeping_suspended);
219
220 do {
Ok 1st time here, so here we are trying to get a read-lock on xtime
using the
221 seq = read_seqbegin(&xtime_lock);
222
So here we copy xtime to ts which cannot be atomic due to the size of
xtime (on x86)
No care is taken if xtime is currrently being update, so in theory ts
could be junk
223 *ts = xtime;
Work out how many nanoseconds has passed since (guessing) xtime was
update but also
include any ntp clock drift corrections (so nsecs > 1 second)
224 nsecs = timekeeping_get_ns();
225
This does nothing on Intel
226 /* If arch requires, add in gettimeoffset() */
227 nsecs += arch_gettimeoffset();
228
[Guessing] If xtime did not change by now - then we are good to break
out the loop
But if it did then lets go round again.
229 } while (read_seqretry(&xtime_lock, seq));
230
Since it could have taken "some" time to get a good complete read of
xtime, we better adjust
it for how long we think it took (also applying any NTP movements). So
now we could return a time
that is greater the xtime's actual value by over a second.
231 timespec_add_ns(ts, nsecs);
232}
Adrian
--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to [email protected]
Please read the FAQ at http://kernelnewbies.org/FAQ