Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Mar 2014 10:28:50 -0400
From:      Ryan Lortie <desrt@desrt.ca>
To:        Baptiste Daroussin <bapt@FreeBSD.org>, hackers@FreeBSD.org
Subject:   Re: [CFR] Kevent timer improvements
Message-ID:  <1394461730.9823.92673865.45316D77@webmail.messagingengine.com>
In-Reply-To: <20140310131632.GI6900@ithaqua.etoilebsd.net>
References:  <20140310131632.GI6900@ithaqua.etoilebsd.net>

next in thread | previous in thread | raw e-mail | index | archive | help
hi Baptiste,

Thanks for the patch!  This helps us a lot and is already a very good
fit for the way we manage event times in GLib.

On Mon, Mar 10, 2014, at 9:16, Baptiste Daroussin wrote:
> Note that NOTE_MONOTONIC is right only valid as EV_ONESHOT as the is the
> behaviour that make sense to me concerning this kind of event, should it
> be different? in that case what behaviour would be expected here?

Speaking somewhat philosophically, it's my opinion that an absolute
timer that is past its timeout is something like a pipe or socket that
has polled as ready for input, but will never be read.  In the case of a
timer based on the real clock, the only way to reverse the condition
would be to change the clock backwards.  For monotonic time, there is no
way to reverse the condition.  This is distinctly different from
periodic timers where the condition can become ready and then "more
ready" just by the simple passage of more time.

Ideally, I don't believe that we should implicitly add EV_ONESHOT or
even EV_CLEAR to the event mask of absolute timer events.  Although the
user would typically want to do that for themselves, I don't believe
that it makes sense to assume that for them -- they should have the
choice, just as they do with pipes and sockets.

Unfortunately, we are faced with NOTE_ABSOLUTE from Apple, based on real
time, which implies EV_ONESHOT.  If FreeBSD ever plans to implement
NOTE_ABSOLUTE, then having it imply EV_ONESHOT and NOTE_MONOTONIC not
imply EV_ONESHOT would be tastelessly inconsistent.

There are usecases for timers with level-triggered semantics.  In GLib,
our main event dispatch mechanism is based on "sources" (GSource). 
GSource has this API:

"""

void      g_source_set_ready_time   (GSource *source,
                                     gint64 ready_time);

Sets a GSource to be dispatched when the given monotonic time is reached
(or passed). If the monotonic time is in the past (as it always will be
if ready_time is 0) then the source will be dispatched immediately.

If ready_time is -1 then the source is never woken up on the basis of
the passage of time.

Dispatching the source does not reset the ready time. You should do so
yourself, from the source dispatch function.

"""

So we already have level-triggered time in GLib (ie: the source does not
become unready until the ready time is explicitly cleared).

The proposed NOTE_MONOTONIC | NOTE_MICROSECONDS corresponds almost
exactly to the g_source_set_ready_time() API above, except for the
implied EV_ONESHOT clearing the timer.

A common request that we get in GLib (not currently implemented, but
hopefully soon) is that people want to embed GLib into another mainloop
like libev, etc.  In order to do this, we want to give them a file
descriptor that polls as ready whenever we have work to do (ie: sources
to dispatch).  It is clear that kqueue() would make a good file
descriptor to use for this purpose.

If the timer event is automatically cleared from this descriptor after
the first report then the file descriptor that we pass for embedding in
another loop will no longer poll as ready.

A workaround that we use to solve this problem on Mac OS is to create a
second kqueue() and add the timer to it.  We never call kevent() to
collect events from this kqueue, so the timer event is never cleared. 
We add this second kqueue to the main kqueue and then we have our
level-triggered semantics.  Having NOTE_MONOTONIC imply EV_ONESHOT would
mean that we have to do the same on FreeBSD.  It works, but it seems
very strange that it is necessary to go to such lengths to get the
desired behaviour.

So if Apple already has NOTE_ABSOLUTE implying EV_ONESHOT, and
NOTE_MONOTONIC should strive to be consistent with NOTE_ABSOLUTE, but
implying EV_ONESHOT is potentially harmful, then what to do?  I'd
suggest the introduction of another flag here to reverse (imho) Apple's
design mistake -- perhaps called NOTE_LEVEL_TRIGGERED or something like
that.

As I mentioned, I can get by without this, simply by using the
two-kqueues trick, but I think the fact that such a trick is required
(to get any behaviour at all, reasonable or otherwise) is an indication
that a mistake was made somewhere along the way.

Thanks very much for the time you've put into preparing this patch and
into understanding my arguments about it.  It really is almost exactly
what we need (and, if combined with kevent64, already puts FreeBSD into
a place where it will have the best implementation of the mainloop of
any platform that GLib runs on).

Cheers



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1394461730.9823.92673865.45316D77>