User code can tell if it is in vcore context (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 28 Feb 2011 19:11:10 +0000 (11:11 -0800)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:59 +0000 (17:35 -0700)
Use the function in_vcore_context().  Also moved some functions to
vcore.h that can be easily inlined.

Rebuild your cross compiler.

tests/mhello.c
tests/pthread_test.c
tools/compilers/gcc-glibc/glibc-2.11.1-ros/sysdeps/ros/start.c
user/parlib/include/vcore.h
user/parlib/vcore.c
user/pthread/pthread.c

index b351b19..fbe1ed5 100644 (file)
@@ -32,6 +32,9 @@ int main(int argc, char** argv)
 
        mcs_barrier_init(&b, max_vcores());
 
 
        mcs_barrier_init(&b, max_vcores());
 
+       /* vcore_context test */
+       assert(!in_vcore_context());
+       
        /* prep indirect ev_q.  Note we grab a big one */
        indirect_q = get_big_event_q();
        indirect_q->ev_flags = EVENT_IPI;
        /* prep indirect ev_q.  Note we grab a big one */
        indirect_q = get_big_event_q();
        indirect_q->ev_flags = EVENT_IPI;
@@ -82,6 +85,8 @@ int main(int argc, char** argv)
                retval = vcore_request(max_vcores());
                //retval = vcore_request(5);
                printf("This is vcore0, right after vcore_request, retval=%d\n", retval);
                retval = vcore_request(max_vcores());
                //retval = vcore_request(5);
                printf("This is vcore0, right after vcore_request, retval=%d\n", retval);
+               /* vcore_context test */
+               assert(!in_vcore_context());
        }
 
        /* test notifying my vcore2 */
        }
 
        /* test notifying my vcore2 */
@@ -127,6 +132,9 @@ void vcore_entry(void)
        static bool first_time = TRUE;
 
        temp = 0xcafebabe;
        static bool first_time = TRUE;
 
        temp = 0xcafebabe;
+       /* vcore_context test (don't need to do this anywhere) */
+       assert(in_vcore_context());
+
 /* begin: stuff userspace needs to do to handle notifications */
 
        struct preempt_data *vcpd;
 /* begin: stuff userspace needs to do to handle notifications */
 
        struct preempt_data *vcpd;
index 73aa037..1f66856 100644 (file)
@@ -23,6 +23,7 @@ void *my_retvals[NUM_TEST_THREADS];
 __thread int my_id;
 void *yield_thread(void* arg)
 {      
 __thread int my_id;
 void *yield_thread(void* arg)
 {      
+       assert(!in_vcore_context());
        for (int i = 0; i < 10; i++) {
                printf_safe("[A] pthread %d on vcore %d\n", pthread_self()->id, vcore_id());
                pthread_yield();
        for (int i = 0; i < 10; i++) {
                printf_safe("[A] pthread %d on vcore %d\n", pthread_self()->id, vcore_id());
                pthread_yield();
index 27f8b9c..d8ef182 100644 (file)
@@ -11,6 +11,7 @@ void** __vcore_thread_control_blocks = NULL;
 weak_alias(__vcore_thread_control_blocks,vcore_thread_control_blocks)
 
 __thread int __vcoreid = 0;
 weak_alias(__vcore_thread_control_blocks,vcore_thread_control_blocks)
 
 __thread int __vcoreid = 0;
+__thread bool __vcore_context = FALSE;
 
 void
 __vcore_entry(void)
 
 void
 __vcore_entry(void)
@@ -43,6 +44,7 @@ _start(void)
        {
                set_tls_desc(__vcore_thread_control_blocks[id],id);
                __vcoreid = id;
        {
                set_tls_desc(__vcore_thread_control_blocks[id],id);
                __vcoreid = id;
+               __vcore_context = TRUE;
                vcore_entry();
                failmsg("why did vcore_entry() return?");
                goto diediedie;
                vcore_entry();
                failmsg("why did vcore_entry() return?");
                goto diediedie;
index 7111d56..c34d235 100644 (file)
@@ -6,6 +6,7 @@ extern "C" {
 #endif
 
 #include <arch/vcore.h>
 #endif
 
 #include <arch/vcore.h>
+#include <sys/param.h>
 #include <string.h>
 
 /*****************************************************************************/
 #include <string.h>
 
 /*****************************************************************************/
@@ -35,20 +36,46 @@ extern struct schedule_ops *sched_ops;
 
 /* Defined by glibc; Must be implemented by a user level threading library */
 extern void vcore_entry();
 
 /* Defined by glibc; Must be implemented by a user level threading library */
 extern void vcore_entry();
+/* Declared in glibc's start.c */
+extern __thread bool __vcore_context;
 
 /* Utility Functions */
 void *allocate_tls(void);
 
 /* Vcore API functions */
 
 /* Utility Functions */
 void *allocate_tls(void);
 
 /* Vcore API functions */
+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 void enable_notifs(uint32_t vcoreid);
+static inline void disable_notifs(uint32_t vcoreid);
 int vcore_init(void);
 int vcore_init(void);
-int vcore_id(void);
 int vcore_request(size_t k);
 void vcore_yield(void);
 int vcore_request(size_t k);
 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);
 
 bool check_preempt_pending(uint32_t vcoreid);
 void clear_notif_pending(uint32_t vcoreid);
 
+/* Inlines */
+static inline size_t max_vcores(void)
+{
+       return MIN(__procinfo.max_vcores, MAX_VCORES);
+}
+
+static inline size_t num_vcores(void)
+{
+       return __procinfo.num_vcores;
+}
+
+static inline int vcore_id(void)
+{
+       return __vcoreid;
+}
+
+static inline bool in_vcore_context(void)
+{
+       return __vcore_context;
+}
+
 static inline void enable_notifs(uint32_t vcoreid)
 {
        __procdata.vcore_preempt_data[vcoreid].notif_enabled = TRUE;
 static inline void enable_notifs(uint32_t vcoreid)
 {
        __procdata.vcore_preempt_data[vcoreid].notif_enabled = TRUE;
index c2cfcef..2d3eb26 100644 (file)
@@ -158,20 +158,6 @@ void vcore_yield()
        sys_yield(0);
 }
 
        sys_yield(0);
 }
 
-size_t max_vcores()
-{
-       return MIN(__procinfo.max_vcores, MAX_VCORES);
-}
-
-size_t num_vcores()
-{
-       return __procinfo.num_vcores;
-}
-
-int vcore_id()
-{
-       return __vcoreid;
-}
 
 /* Deals with a pending preemption (checks, responds).  If the 2LS registered a
  * function, it will get run.  Returns true if you got preempted.  Called
 
 /* Deals with a pending preemption (checks, responds).  If the 2LS registered a
  * function, it will get run.  Returns true if you got preempted.  Called
index df6cd19..98cc05a 100644 (file)
@@ -87,6 +87,7 @@ void __attribute__((noreturn)) vcore_entry()
 
        /* Should always have notifications disabled when coming in here. */
        assert(vcpd->notif_enabled == FALSE);
 
        /* Should always have notifications disabled when coming in here. */
        assert(vcpd->notif_enabled == FALSE);
+       assert(in_vcore_context());
 
        check_preempt_pending(vcoreid);
        handle_events(vcoreid);
 
        check_preempt_pending(vcoreid);
        handle_events(vcoreid);