On 8/5/23 00:49, Scott Cheloha wrote: > On Sat, Aug 05, 2023 at 12:17:48AM -0400, aisha wrote: >> On 22/09/10 01:53PM, Visa Hankala wrote: >>> On Wed, Aug 31, 2022 at 04:48:37PM -0400, aisha wrote: >>>> I've added a patch which adds support for NOTE_{,U,M,N}SECONDS for >>>> EVFILT_TIMER in the kqueue interface. >>> It sort of makes sense to add an option to specify timeouts in >>> sub-millisecond precision. It feels complete overengineering to add >>> multiple time units on the level of the kernel interface. However, >>> it looks that FreeBSD and NetBSD have already done this following >>> macOS' lead... >>> >>>> I've also added the NOTE_ABSTIME but haven't done any actual implementation >>>> there as I am not sure how the `data` field should be interpreted (is it >>>> absolute time in seconds since epoch?). >>> I think FreeBSD and NetBSD take NOTE_ABSTIME as time since the epoch. >>> >>> Below is a revised patch that takes into account some corner cases. >>> It tries to be API-compatible with FreeBSD and NetBSD. I have adjusted >>> the NOTE_{,M,U,N}SECONDS flags so that they are enum-like. >>> >>> The manual page bits are from NetBSD. >>> >>> It is quite late to introduce a feature like this within this release >>> cycle. Until now, the timer code has ignored the fflags field. There >>> might be pieces of software that are careless with struct kevent and >>> that would break as a result of this patch. Programs that are widely >>> used on different BSDs are probably fine already, though. >> Sorry, I had forgotten this patch for a long time!!! I've been running with >> this for a while now and it's been working nicely. > Where is this being used in ports? I think having "one of each" for > seconds, milliseconds, microseconds, and nanoseconds is (as visa > noted) way, way over-the-top.
I was using it with a port that I sent out a while ago but never got into tree (was before I joined the project) - https://marc.info/?l=openbsd-ports&m=165715874509440&w=2 I also agree with it being over the top but that's the way it is in net/freebsd, I'm also fine with breaking compatibility and only keeping nano, no preferences either way. > The original EVFILT_TIMER supported only milliseconds, yes. Given > that it debuted in the late 90s, I think that was a bad choice. But > when milliseconds were insufficiently precise, the obvious thing would > be to add support for nanoseconds... and then stop. > > The decision to use the UTC clock with no option to select a different > clockid_t for NOTE_ABSTIME is also unfortunate. Yes, furthermore this was very unclear as I couldn't find this in the man pages for either of net/freebsd. > > Grumble. > >> I had an unrelated question inlined. >> >> [...] >>> static void >>> -filt_timer_timeout_add(struct knote *kn) >>> +filt_timeradd(struct knote *kn, struct timespec *ts) >>> { >>> - struct timeval tv; >>> + struct timespec expiry, now; >>> struct timeout *to = kn->kn_hook; >>> int tticks; >>> >>> - tv.tv_sec = kn->kn_sdata / 1000; >>> - tv.tv_usec = (kn->kn_sdata % 1000) * 1000; >>> - tticks = tvtohz(&tv); >>> - /* Remove extra tick from tvtohz() if timeout has fired before. */ >>> + if (kn->kn_sfflags & NOTE_ABSTIME) { >>> + nanotime(&now); >>> + if (timespeccmp(ts, &now, >)) { >>> + timespecsub(ts, &now, &expiry); >>> + /* XXX timeout_at_ts */ >>> + timeout_add(to, tstohz(&expiry)); > visa: > > we should use timeout_abs_ts() here. I need to adjust it, though. > >>> + } else { >>> + /* Expire immediately. */ >>> + filt_timerexpire(kn); >>> + } >>> + return; >>> + } >>> + >>> + tticks = tstohz(ts); >>> + /* Remove extra tick from tstohz() if timeout has fired before. */ >>> if (timeout_triggered(to)) >>> tticks--; >> I always wondered why one tick was removed, is one tick really >> that important? And does a timeout firing only cost one tick? > When you convert a duration to a count of ticks with tstohz(), it adds > an extra tick to the result to keep you from undershooting your > timeout. You start counting your timeout at the start of the *next* > tick, otherwise the timeout might fire early. However, after the > timeout has expired once, you no longer need the extra tick because > you can (more or less) assume that the timeout is running at the start > of the new tick. > > I know that sounds a little fuzzy, but in practice it works. Haha, these are the kind of weird idiosyncrasies that are fun to know about. Thank you very much for the explanation! :D So I went around looking at how large a tick really is and seems like we get it through kern.clockrate (from man tick) aisha@fwall ~ $ sysctl kern.clockrate kern.clockrate=tick = 10000, hz = 100, profhz = 1000, stathz = 100 so presumably each tick is 1/10000 of a second (is this right?), and things are getting scheduled in terms of ticks, so how is it even possible to get nanosecond level accuracy there? >From more looking around it seems like atleast x86 has TSC which provides better resolution (presumably similar things exist for other archs) but I don't see it being used anywhere here in an obvious fashion. man pctr doesn't mention it being used for time measurement.