handle_events() unconditionally
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 10 Oct 2014 18:38:43 +0000 (11:38 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 13 Oct 2014 19:47:54 +0000 (12:47 -0700)
If we condition on notif_pending and we don't drain the event queue
completely (due to a handler not returning perhaps), then the next time
we try to handle_events, we would have bailed out - even if the mboxes
weren't empty.

Another concern is that if we handle_events, clear notif_pending, and
then we run a handler that doesn't return, that we someone slip out of
vcore context in the future without checking messages.  Any case
involving a handler that doesn't return should result in a fresh vcore
context starting up, which checks events.  This means that event
handlers cannot pop directly into uthreads.  ev_might_not_return() won't
help you with that, since it covers cases where we handle another vcores
mbox, not our own mbox.

user/parlib/event.c

index 6407591..eb6b74c 100644 (file)
@@ -281,7 +281,7 @@ void handle_ev_ev(struct event_msg *ev_msg, unsigned int ev_type, void *data)
        handle_event_q(ev_q);
 }
 
-/* Attempts to handle events, if notif_pending.  The kernel always sets
+/* Handles VCPD events (public and private).  The kernel always sets
  * notif_pending after posting a message to either public or private mailbox.
  * When this returns, as far as we are concerned, notif_pending is FALSE.
  * However, a concurrent kernel writer could have reset it to true.  This is
@@ -293,12 +293,10 @@ int handle_events(uint32_t vcoreid)
 {
        struct preempt_data *vcpd = vcpd_of(vcoreid);
        int retval = 0;
-       if (vcpd->notif_pending) {
-               vcpd->notif_pending = FALSE;
-               wrmb(); /* prevent future reads from happening before notif_p write */
-               retval += handle_mbox(&vcpd->ev_mbox_private);
-               retval += handle_mbox(&vcpd->ev_mbox_public);
-       }
+       vcpd->notif_pending = FALSE;
+       wrmb(); /* prevent future reads from happening before notif_p write */
+       retval += handle_mbox(&vcpd->ev_mbox_private);
+       retval += handle_mbox(&vcpd->ev_mbox_public);
        return retval;
 }