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.

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.

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.

Reply via email to