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.

Reply via email to