Vcore helper for clearing notif_pending
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 25 Feb 2011 00:42:36 +0000 (16:42 -0800)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:59 +0000 (17:35 -0700)
Clears pending, catches most of the races.  pop_ros_tf() is still the
final point to catch those sorts of things.  Changes to ros/membar.h are
cosmetic, so you shouldn't need to reinstall kernel headers or rebuild
your XCC.

kern/arch/i686/ros/membar.h
kern/arch/sparc/ros/membar.h
tests/eth_audio.c
tests/mhello.c
tests/msr_get_cores.c
tests/msr_get_singlecore.c
tests/syscall.c
user/parlib/include/vcore.h
user/parlib/vcore.c
user/pthread/pthread.c

index 5ba760a..5e38bf9 100644 (file)
@@ -8,7 +8,8 @@
 /* Compiler memory barrier */
 #define cmb() ({ asm volatile("" ::: "memory"); })
 /* Force a wmb, used in cases where an IPI could beat a write, even though
- *  * write-orderings are respected. TODO: this probably do what you want. */
+ * write-orderings are respected.
+ * TODO: this probably doesn't do what you want. */
 #define wmb_f() ({ asm volatile("sfence"); })
 
 #endif
index 8813ce5..a8bd24b 100644 (file)
@@ -7,7 +7,7 @@
 /* Compiler memory barrier */
 #define cmb() ({ asm volatile("" ::: "memory"); })
 /* Force a wmb, used in cases where an IPI could beat a write, even though
- *  * write-orderings are respected.  (Used by x86) */
+ * write-orderings are respected.  (Used by x86) */
 #define wmb_f() wmb()
 
 #endif
index 3f7f3aa..25ac8a1 100644 (file)
@@ -121,8 +121,7 @@ void vcore_entry(void)
         * set the appropriate TLS.  On x86, this will involve changing the LDT
         * entry for this vcore to point to the TCB of the new user-thread. */
        if (vcoreid == 0) {
-               vcpd->notif_pending = 0;
-               /* Do one last check for notifs after clearing pending */
+               clear_notif_pending(vcoreid);
                set_tls_desc(core0_tls, 0);
                /* Load silly state (Floating point) too */
                pop_ros_tf(&vcpd->notif_tf, vcoreid);
index 08f3cc7..b351b19 100644 (file)
@@ -149,8 +149,7 @@ void vcore_entry(void)
                        udelay(5000000);
                } */
                printf("restarting vcore0 from userspace\n");
-               vcpd->notif_pending = 0;
-               /* Do one last check for notifs after clearing pending */
+               clear_notif_pending(vcoreid);
                /* // testing for missing a notif
                if (first_time) {
                        first_time = FALSE;
index d6fd37a..bf6c499 100644 (file)
@@ -101,7 +101,7 @@ void vcore_entry(void)
         * set the appropriate TLS.  On x86, this will involve changing the LDT
         * entry for this vcore to point to the TCB of the new user-thread. */
        if (vcoreid == 0) {
-               vcpd->notif_pending = 0;
+               clear_notif_pending(vcoreid);
                set_tls_desc(core0_tls, 0);
                /* Load silly state (Floating point) too */
                pop_ros_tf(&vcpd->notif_tf, vcoreid);
index 0c74dfe..2023ed8 100644 (file)
@@ -102,7 +102,7 @@ void vcore_entry(void)
         * set the appropriate TLS.  On x86, this will involve changing the LDT
         * entry for this vcore to point to the TCB of the new user-thread. */
        if (vcoreid == 0) {
-               vcpd->notif_pending = 0;
+               clear_notif_pending(vcoreid);
                set_tls_desc(core0_tls, 0);
                /* Load silly state (Floating point) too */
                pop_ros_tf(&vcpd->notif_tf, vcoreid);
index 924b237..461f4a9 100644 (file)
@@ -120,8 +120,7 @@ void vcore_entry(void)
 
        /* Restart vcore0's context. */
        if (vcoreid == 0) {
-               vcpd->notif_pending = 0;
-               /* TODO: Do one last check for notifs after clearing pending */
+               clear_notif_pending(vcoreid);
                set_tls_desc(core0_tls, 0);
                /* Load silly state (Floating point) too */
                pop_ros_tf(&vcpd->notif_tf, vcoreid);
index 1cbfa87..000fb79 100644 (file)
@@ -46,6 +46,7 @@ void vcore_yield(void);
 size_t max_vcores(void);
 size_t num_vcores(void);
 bool check_preempt_pending(uint32_t vcoreid);
+void clear_notif_pending(uint32_t vcoreid);
 
 static inline void enable_notifs(uint32_t vcoreid)
 {
index 035203a..c2cfcef 100644 (file)
@@ -10,6 +10,8 @@
 #include <sys/mman.h>
 #include <rstdio.h>
 #include <glibc-tls.h>
+#include <event.h>
+#include <ros/arch/membar.h>
 
 /* starting with 1 since we alloc vcore0's stacks and TLS in vcore_init(). */
 static size_t _max_vcores_ever_wanted = 1;
@@ -188,3 +190,18 @@ bool check_preempt_pending(uint32_t vcoreid)
        }
        return retval;
 }
+
+/* Clear pending, and try to handle events that came in between a previous call
+ * to handle_events() and the clearing of pending.  While it's not a big deal,
+ * we'll loop in case we catch any.  Will break out of this once there are no
+ * events, and we will have send pending to 0. 
+ *
+ * Note that this won't catch every race/case of an incoming event.  Future
+ * events will get caught in pop_ros_tf() */
+void clear_notif_pending(uint32_t vcoreid)
+{
+       do {
+               cmb();
+               __procdata.vcore_preempt_data[vcoreid].notif_pending = 0;
+       } while (handle_events(vcoreid));
+}
index cd2cd44..df6cd19 100644 (file)
@@ -93,10 +93,7 @@ void __attribute__((noreturn)) vcore_entry()
        // TODO: consider making this restart path work for restarting as well as
        // freshly starting
        if (current_thread) {
-               vcpd->notif_pending = 0;
-               /* Do one last check for notifs after clearing pending */
-               // TODO: call the handle_notif() here (first)
-
+               clear_notif_pending(vcoreid);
                set_tls_desc(current_thread->tls_desc, vcoreid);
                /* Pop the user trap frame */
                pop_ros_tf(&vcpd->notif_tf, vcoreid);
@@ -123,9 +120,7 @@ void __attribute__((noreturn)) vcore_entry()
        current_thread = new_thread;
        printd("[P] Vcore %d is starting pthread %d\n", vcoreid, new_thread->id);
 
-       vcpd->notif_pending = 0;
-       /* Do one last check for notifs after clearing pending */
-       // TODO: call the handle_notif() here (first)
+       clear_notif_pending(vcoreid);
        set_tls_desc(new_thread->tls_desc, vcoreid);
 
        /* Load silly state (Floating point) too.  For real */