Fixes uthread sysc block logic
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 18 Mar 2011 00:24:27 +0000 (17:24 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:36:00 +0000 (17:36 -0700)
The old version would only screw up if we blocked in uthread_init()
before we entered _M mode.  This way is much clearer, and provides an
approved way to see if you're _M or not.

user/parlib/include/vcore.h
user/parlib/uthread.c

index 4afad10..fd5faf1 100644 (file)
@@ -41,6 +41,7 @@ static inline size_t max_vcores(void);
 static inline size_t num_vcores(void);
 static inline int vcore_id(void);
 static inline bool in_vcore_context(void);
+static inline bool in_multi_mode(void);
 static inline void __enable_notifs(uint32_t vcoreid);
 static inline void disable_notifs(uint32_t vcoreid);
 static inline bool notif_is_enabled(uint32_t vcoreid);
@@ -72,6 +73,11 @@ static inline bool in_vcore_context(void)
        return __vcore_context;
 }
 
+static inline bool in_multi_mode(void)
+{
+       return (num_vcores() > 0) ? TRUE : FALSE;
+}
+
 /* Only call this if you know what you are doing. */
 static inline void __enable_notifs(uint32_t vcoreid)
 {
index a255e96..a20cfd0 100644 (file)
@@ -45,7 +45,7 @@ static int uthread_init(void)
         * restart your _S with notifs disabled, which is a path to confusion. */
        __enable_notifs(0);
        /* Get ourselves into _M mode.  Could consider doing this elsewhere... */
-       while (num_vcores() < 1) {
+       while (!in_multi_mode()) {
                vcore_request(1);
                /* TODO: consider blocking */
                cpu_relax();
@@ -235,8 +235,8 @@ void ros_syscall_blockon(struct syscall *sysc)
                __ros_syscall_blockon(sysc);
                return;
        }
-       if (!sched_ops->thread_blockon_sysc || !current_uthread) {
-               /* There isn't a 2LS op for blocking.  Spin for now. */
+       if (!sched_ops->thread_blockon_sysc || !in_multi_mode()) {
+               /* There isn't a 2LS op for blocking, or we're _S.  Spin for now. */
                __ros_syscall_blockon(sysc);
                return;
        }
@@ -244,6 +244,7 @@ void ros_syscall_blockon(struct syscall *sysc)
        if (sysc->flags & (SC_DONE | SC_PROGRESS))
                return;
        /* So yield knows we are blocking on something */
+       assert(current_uthread);
        current_uthread->sysc = sysc;
        uthread_yield();
 }