RE: Why time() and gettimeofday() can return different values

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> From: Mulyadi Santosa [mailto:mulyadi.santosa@xxxxxxxxx]
> 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 ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ




[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux