> On Oct 29, 2018, at 17:21, Robert Elz <k...@munnari.oz.au> wrote: > > | We are talking about internal kernel data. If you need $uptime, you > | could expose it like $boottime. > > We could, but deisigning a system where now - boottime != uptime is > kind of weird, don't you think? boottime is where it all starts, if boottime > is X, and uptime is Y, then X + Y should be now. > > None of that means that there can't be activity before boot time of > course, we need to pick an epoch, (just like unix timestamps have > 0 at 1 Jan 1970) and it should be something meaningful, with > some practical reason to exist - but pick a point to call 0 does > not mean earlier times don't exist.
Note that time_second(9) says boottime is “the system boot time” (in UTC, implicitly) while uptime is “the time elapsed since boot”. I believe this unambiguously defines boottime to be the (UTC) time when uptime was zero; boottime is uptime’s epoch. This doesn’t mean that boottime needs to be set when uptime is zero, it just means that when boottime is set it needs to be set to (time(now) - uptime(now)) rather than just time(now). That it is initialized to the latter is the bug. It may be worth pointing out that the code in kern/kern_tc.c is written to maintain the identity time = uptime + boottime at all times, except that it instead maintains a local version of boottime in the local variable timebasebin. While it is hard to deduce by reading it the precision timescale that is maintained in there is actually uptime; when something wants time it reads uptime(now) and adds timebasebin to it (i.e. uptime + boottime) to compute the time of day. timebasebin is essentially a version of ‘boottime’ that is initialized and maintained correctly, the time of day of the uptime epoch. I suspect the easiest way to fix the bug would be to eliminate the independent initialization and maintenance of the boottime variable in init_main.c and kern_time.c in favor of adding a bintime2timespec(&timebasebin, &boottime); after timebasebin is updated in kern_tc.c:tc_setclock(). The code that manipulates boottime outside of kern_tc.c is actually a leftover vestige of the clock support code prior to timecounters that probably should have disappeared when the latter was implemented. As a quibble, the code in kern_todr.c:inittodr() could probably be improved a bit. If reading the todr is successful what is returned is about the best estimate of time(now) that we have so calling tc_setclock() with this value is appropriate. If it falls back to the file system time, however, we can not only be sure that this isn’t time(now) but is in fact a time that predates the uptime epoch, so calling tc_setclock(filesystemtime + uptime(now) + maybe_a_fudge_factor) would produce a time(now) that is at least a few seconds closer to reality. Dennis