Both calls are implemented as kernel syscalls. Both functions end up reading a struct timekeeper
, both refer to the very same instance. But they differ in what they do with it:
time():
uses the get_seconds()
function, which is a shortcut to this:
struct timekeeper *tk = &timekeeper;
return tk->xtime_sec;
it just returns xktime_sec
.
gettimeofday()
:
gettimeofday()
on the other hand uses do_gettimeofday()
(via getnstimeofday
) which reads both fields xktime_sec
as well as xktime_nsec
(via timekeeping_get_ns
). Here it might happen that xktime_nsec
holds more nanoseconds than a second. This potential extra time is used to increase the tv_sec
field by calling the function timespec_add_ns()
which does this:
a->tv_sec += __iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns);
a->tv_nsec = ns;
So, tv_sec
might get bigger than the xktime_sec
field was. And there you have it: a little difference in what time()
gives you and what gettimeofday()
gives you.
I fought against this issue in fluxbox today and until a better solution occurs I live with this:
uint64_t t_usec = gettimeofday_in_usecs(); // calcs usecs since epoch
time_t t = static_cast<time_t>(t_usec / 1000000L);