I agree, the decision is whether we want bintime in the export format.

For the microtime/nanotime question (see kern/kern_tc.c):
    binuptime()=scaled time counter read
    bintime()=binuptime()+bootimeoffset
    nanotime()=bintime()+bintime2timespec()
    microtime()=bintime()+bintime2timeval()

So any use of microtime and nanotime does the conversion from bintime to the required format. So timestamp collection incurs this conversion overhead.

The get-versions are cheaper, but they only provide a cached timestamp from basically the last hardclock() event. So they are not really suitable for high resolution time stamping - but probably ok for file system time stamps and probably device drivers.

Yes - time is a time consuming topic at a certain level and you are almost always certain to get it wrong :-)

Frank


On 01/04/17 10:18, Paul Goyette wrote:
On Wed, 4 Jan 2017, Frank Kardel wrote:

On 01/04/17 09:37, Paul Goyette wrote:
On Wed, 4 Jan 2017, Frank Kardel wrote:

I would also suggest a 64 bit fraction like in struct bintime, which we already have and use internally for timekeeping anyway along with the timespec, timeval conversion functions. Thus collecting can be faster as we don't need to make the conversions when collectiing. I deem converting at userlevel the least worry.

For time stamp fetching see "man 9 microtime" or kern/kern_tc.c:{get,}bin{,up}time(). "get"-versions are cheaper, but only updated at hardclock(). The non-get ones are directly related
to the current time counter.

Using bintime as the "native" timestamp representation would require
changes to the in-kernel structures, rather than just those used for
I see - I didn't look at the event collection yet. bintime is the native kernel timestamp format,
though it is not used everywhere.
exporting the data to userland.  And if the in-kernel structures are
changed, then we'll have to be able to print them from within the
kernel.

For userland we could just do float- or double-divide to convert the
fraction to printable format;
Yep that's the usual procedure.
sys/time.h already has a non-fp conversion to timeval/timespec.

  static __inline void
  bintime2timespec(const struct bintime *bt, struct timespec *ts)
  {

           ts->tv_sec = bt->sec;
           ts->tv_nsec =
               (long)(((uint64_t)1000000000 * (uint32_t)(bt->frac >>
  32)) >> 32);
  }

it's not clear how we could print these
values from within the kernel (where we're not allowed to use fp?).
Would converting to timespec/timeval and the usual %d.%06?d printf-fmt be an option without creating a horrible data wrangling mess? (I don't know how many
printfs would be affected).

There's not many printfs to worry about - exactly 1 in the kernel, and only 1 that I know of in userland (in vmstat.c). (The kernel one is intended to be called via ddb(4)'s 'show kernhist' command - or some other debugger, but I guess you could figure out a way to call it from somewhere else.)

As long as we can guarantee that a time_t is always 64-bits, I don't see any reason why we can't use the conversion functions from sys/time.h in both kernel and user side.

Of course, it all depends on whether we decide on bintime as the export format.

Just out of curiousity, how expensive is bintime(9), compared to microtime(9) or nanotime(9)? We're already doing microtime to get the in-kernel timestamp, so if bintime(9) is the same cost, it would be better (IMHO) to change the internal value now. Then the only time we need any conversion is at printf() time.



Wow - I never imagined how many worms there were in this little can!

:)




+------------------+--------------------------+------------------------+
| Paul Goyette     | PGP Key fingerprint:     | E-mail addresses:      |
| (Retired)        | FA29 0E3B 35AF E8AE 6651 | paul at whooppee.com   |
| Kernel Developer | 0786 F758 55DE 53BA 7731 | pgoyette at netbsd.org |
+------------------+--------------------------+------------------------+

Reply via email to