Uthread vc_entry will spin on STEALING
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 29 Nov 2011 23:52:33 +0000 (15:52 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 15 Dec 2011 22:48:41 +0000 (14:48 -0800)
If for any reason STEALING is set, a vcore can't touch its
current_uthread.  2LSs don't need to worry about it; uthread code will
deal with it before calling out to a 2LS.  Preemption recovery code will
muck with this.

user/parlib/event.c
user/parlib/uthread.c

index d435d50..0bd6b11 100644 (file)
@@ -183,9 +183,6 @@ static int handle_mbox(struct event_mbox *ev_mbox, unsigned int flags)
 {
        int retval = 0;
        uint32_t vcoreid = vcore_id();
-       /* Make sure no one made it in here with a DONT_MIGRATE */
-       if (current_uthread)
-               assert(!(current_uthread->flags & UTHREAD_DONT_MIGRATE));
        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);
index e3d5b21..da0147d 100644 (file)
@@ -71,12 +71,21 @@ int uthread_lib_init(struct uthread *uthread)
 void __attribute__((noreturn)) uthread_vcore_entry(void)
 {
        uint32_t vcoreid = vcore_id();
+       struct preempt_data *vcpd = &__procdata.vcore_preempt_data[vcoreid];
        /* Should always have notifications disabled when coming in here. */
        assert(!notif_is_enabled(vcoreid));
        assert(in_vcore_context());
+       /* If someone is stealing our uthread (from when we were preempted before),
+        * we can't touch our uthread.  But we might be the last vcore around, so
+        * we'll handle preemption events. */
+       while (atomic_read(&vcpd->flags) & VC_UTHREAD_STEALING) {
+               handle_event_q(preempt_ev_q);
+               cpu_relax();
+       }
        /* If we have a current uthread that is DONT_MIGRATE, pop it real quick and
-        * let it disable notifs (like it wants to).  It's important that we don't
-        * check messages/handle events with a DONT_MIGRATE uthread. */
+        * let it disable notifs (like it wants to).  Other than dealing with
+        * preemption events, we shouldn't do anything in vc_ctx when we have a
+        * DONT_MIGRATE uthread. */
        if (current_uthread && (current_uthread->flags & UTHREAD_DONT_MIGRATE))
                __run_current_uthread_raw();
        /* Otherwise, go about our usual vcore business (messages, etc). */