Bit messages are now flagged (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 9 Dec 2011 23:12:26 +0000 (15:12 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 15 Dec 2011 22:48:42 +0000 (14:48 -0800)
This saves a scan of the bitmap every time we check events or want to
know if an ev_mbox has messages - even if one of the event handlers
didn't return.

Reinstall your kernel headers.

kern/include/ros/event.h
kern/src/event.c
user/parlib/event.c
user/parlib/include/event.h
user/parlib/uthread.c

index a4047fe..44dc78b 100644 (file)
@@ -69,6 +69,7 @@ struct event_msg {
  * sent (and no message). */
 struct event_mbox {
        struct ucq                                      ev_msgs;
+       bool                                            ev_check_bits;
        uint8_t                                         ev_bitmap[(MAX_NR_EVENT - 1) / 8 + 1];
 };
 
index 6859a9f..7589f6a 100644 (file)
@@ -66,6 +66,8 @@ static void post_ev_msg(struct proc *p, struct event_mbox *mbox,
        /* If they just want a bit (NOMSG), just set the bit */
        if (ev_flags & EVENT_NOMSG) {
                SET_BITMASK_BIT_ATOMIC(mbox->ev_bitmap, msg->ev_type);
+               wmb();
+               mbox->ev_check_bits = TRUE;
        } else {
                send_ucq_msg(&mbox->ev_msgs, p, msg);
        }
index eb5712c..40ff026 100644 (file)
@@ -187,18 +187,10 @@ int handle_mbox_msgs(struct event_mbox *ev_mbox)
 /* Handle an mbox.  This is the receive-side processing of an event_queue.  It
  * takes an ev_mbox, since the vcpd mbox isn't a regular ev_q.  For now, we
  * check for preemptions between each event handler. */
-int handle_mbox(struct event_mbox *ev_mbox, unsigned int flags)
+int handle_mbox(struct event_mbox *ev_mbox)
 {
        int retval = 0;
        uint32_t vcoreid = vcore_id();
-       printd("[event] handling ev_mbox %08p on vcore %d\n", ev_mbox, vcore_id());
-       /* Handle full messages.  Will deal with bits later. */
-       retval = handle_mbox_msgs(ev_mbox);
-       /* Process all bits, if they requested NOMSG.  o/w, we'll skip the bitmask
-        * scan.
-        *
-        * TODO: if they have a flag saying "it's okay to overflow", then we'll want
-        * to check the bits regardless */
        void bit_handler(unsigned int bit) {
                printd("[event] Bit: ev_type: %d\n", bit);
                if (ev_handlers[bit])
@@ -207,9 +199,22 @@ int handle_mbox(struct event_mbox *ev_mbox, unsigned int flags)
                check_preempt_pending(vcoreid);
                /* Consider checking the queue for incoming messages while we're here */
        }
-       if (flags & EVENT_NOMSG)
-               BITMASK_FOREACH_SET(ev_mbox->ev_bitmap, MAX_NR_EVENT, bit_handler,
-                                   TRUE);
+       printd("[event] handling ev_mbox %08p on vcore %d\n", ev_mbox, vcore_id());
+       /* Handle full messages. */
+       retval = handle_mbox_msgs(ev_mbox);
+       /* Process all bits, if the kernel tells us any bit is set.  We don't clear
+        * the flag til after we check everything, in case one of the handlers
+        * doesn't return.  After we clear it, we recheck. */
+       if (ev_mbox->ev_check_bits) {
+               do {
+                       ev_mbox->ev_check_bits = TRUE;  /* in case we don't return */
+                       cmb();
+                       BITMASK_FOREACH_SET(ev_mbox->ev_bitmap, MAX_NR_EVENT, bit_handler,
+                                           TRUE);
+                       ev_mbox->ev_check_bits = FALSE;
+                       wrmb(); /* check_bits written before we check for it being clear */
+               } while (!BITMASK_IS_CLEAR(ev_mbox->ev_bitmap, MAX_NR_EVENT));
+       }
        return retval;
 }
 
@@ -242,11 +247,8 @@ int handle_events(uint32_t vcoreid)
 {
        struct preempt_data *vcpd = vcpd_of(vcoreid);
        int retval = 0;
-       /* TODO: EVENT_NOMSG checks could be painful.  we could either keep track of
-        * whether or not the 2LS has a NOMSG ev_q pointing to its vcpd, or have the
-        * kernel set another flag for "bits" */
-       retval += handle_mbox(&vcpd->ev_mbox_private, EVENT_NOMSG);
-       retval += handle_mbox(&vcpd->ev_mbox_public, EVENT_NOMSG);
+       retval += handle_mbox(&vcpd->ev_mbox_private);
+       retval += handle_mbox(&vcpd->ev_mbox_public);
        return retval;
 }
 
@@ -274,5 +276,5 @@ void handle_event_q(struct event_queue *ev_q)
                return;
        }
        printd("[event] handling ev_q %08p on vcore %d\n", ev_q, vcore_id());
-       handle_mbox(ev_q->ev_mbox, ev_q->ev_flags);
+       handle_mbox(ev_q->ev_mbox);
 }
index f142c94..b849b34 100644 (file)
@@ -34,7 +34,7 @@ extern handle_event_t ev_handlers[];
 void handle_ev_ev(struct event_msg *ev_msg, unsigned int ev_type);
 int handle_events(uint32_t vcoreid);
 void handle_event_q(struct event_queue *ev_q);
-int handle_mbox(struct event_mbox *ev_mbox, unsigned int flags);
+int handle_mbox(struct event_mbox *ev_mbox);
 int handle_mbox_msgs(struct event_mbox *ev_mbox);
 
 #endif /* _EVENT_H */
index 9e5339a..feaeabd 100644 (file)
@@ -94,8 +94,7 @@ void __attribute__((noreturn)) uthread_vcore_entry(void)
        /* Check and see if we wanted ourselves to handle a remote VCPD mbox */
        if (uth_handle_an_mbox) {
                uth_handle_an_mbox = FALSE;
-               /* TODO: need to catch the bits (for now), like in handle_events */
-               handle_mbox(&vcpd_of(uth_rem_vcoreid)->ev_mbox_public, EVENT_NOMSG);
+               handle_mbox(&vcpd_of(uth_rem_vcoreid)->ev_mbox_public);
        }
        /* Otherwise, go about our usual vcore business (messages, etc). */
        check_preempt_pending(vcoreid);