vcore_id() is now implemented using TLS
authorAndrew Waterman <waterman@s143.Millennium.Berkeley.EDU>
Sat, 1 May 2010 04:53:44 +0000 (21:53 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:46 +0000 (17:35 -0700)
on both SPARC and x86.  Rebuild your xcc.

kern/arch/sparc/process.c
kern/arch/sparc/ros/trapframe.h
kern/arch/sparc/trap.h
kern/arch/sparc/trap_entry.S
tests/pthread_test.c
tools/compilers/gcc-glibc/glibc-2.11.1-ros/sysdeps/ros/start.c
user/include/i686/vcore.h
user/include/sparc/vcore.h
user/parlib/vcore.c

index e0a4d5f..3ea9af3 100644 (file)
@@ -21,10 +21,11 @@ proc_init_trapframe(trapframe_t *tf, uint32_t vcoreid,
 
        tf->psr = PSR_S; // but PS = 0
        tf->gpr[14] = stack_top-96;
-       tf->asr13 = vcoreid;
 
        tf->pc = entryp;
        tf->npc = entryp+4;
+
+       tf->gpr[6] = vcoreid;
 }
 
 void proc_secure_trapframe(struct trapframe *tf)
index 3ae9d34..c7f2d42 100644 (file)
@@ -13,8 +13,6 @@ typedef struct trapframe
        uint32_t wim;
        uint32_t tbr;
        uint32_t y;
-       uint32_t asr13;
-       uint32_t pad;
        uint32_t fault_status;
        uint32_t fault_addr;
        uint64_t timestamp;
index f50f390..069dbc7 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef ROS_INC_ARCH_TRAP_H
 #define ROS_INC_ARCH_TRAP_H
 
-#define SIZEOF_TRAPFRAME_T     0xB0
+#define SIZEOF_TRAPFRAME_T     0xA8
 #define SIZEOF_KERNEL_MESSAGE_T        0x18
 
 #ifndef __ASSEMBLER__
index 8a8cc2d..0167040 100644 (file)
@@ -22,7 +22,7 @@
        set     0x400,%g3    ;\
        lda     [%g2] 4,%g2  ;\
        lda     [%g3] 4,%g3  ;\
-       std     %g2,[tf+160]
+       std     %g2,[tf+152]
 
 // Macro to restore same.
 #define RESTORE_MINIMAL_TF(tf) \
@@ -165,9 +165,6 @@ env_pop_tf:
        ldd     [%g2+120],%i6
        save
 
-       ld      [%o0+152],%l6
-       mov     %l6,%asr13
-
        RESTORE_MINIMAL_TF(%o0)
 
        // save_rest_of_tf saves what SAVE_MINIMAL_TF doesn't.
@@ -176,13 +173,11 @@ save_rest_of_tf:
 
        mov     %wim,%o4
        st      %o4,[%o0+140]
-       mov     %asr13,%o5
-       st      %o5,[%o0+152]
 
        lda     [%g0] 2,%o4
        mov     4,%o5
        lda     [%o5] 2,%o5
-       std     %o4,[%o0+168]
+       std     %o4,[%o0+160]
 
        mov     %o0,%g2
 
index 425934c..73aa037 100644 (file)
@@ -5,8 +5,8 @@
 #include <unistd.h>
 
 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
-//#define printf_safe(...) {}
-#define printf_safe(...) \
+#define printf_safe(...) {}
+//#define printf_safe(...) \
        pthread_mutex_lock(&lock); \
        printf(__VA_ARGS__); \
        pthread_mutex_unlock(&lock);
@@ -15,7 +15,7 @@ pthread_t t1;
 pthread_t t2;
 pthread_t t3;
 
-#define NUM_TEST_THREADS 10
+#define NUM_TEST_THREADS 1000
 
 pthread_t my_threads[NUM_TEST_THREADS];
 void *my_retvals[NUM_TEST_THREADS];
@@ -74,5 +74,6 @@ int main(int argc, char** argv)
                        printf_safe("[A] Successfully joined on thread %d (retval: %p)\n", i,
                                    my_retvals[i]);
                }
+               break;
        }
 } 
index 1b06222..5db1f47 100644 (file)
@@ -10,6 +10,8 @@
 void** __vcore_thread_control_blocks = NULL;
 weak_alias(__vcore_thread_control_blocks,vcore_thread_control_blocks)
 
+__thread int __vcoreid = 0;
+
 void
 __vcore_entry(void)
 {
@@ -39,7 +41,8 @@ _start(void)
        // acquire a TCB.
        if(init || (id != 0))
        {
-               TLS_INIT_TP(__vcore_thread_control_blocks[id],0);
+               set_tls_desc(__vcore_thread_control_blocks[id],id);
+               __vcoreid = id;
                vcore_entry();
                failmsg("why did vcore_entry() return?");
                goto diediedie;
index 107a374..54fd7ed 100644 (file)
@@ -7,6 +7,8 @@
 #include <ros/syscall.h>
 #include <ros/arch/mmu.h>
 
+extern __thread int __vcoreid;
+
 /* Pops an ROS kernel-provided TF, reanabling notifications at the same time.
  * A Userspace scheduler can call this when transitioning off the transition
  * stack.
@@ -140,14 +142,16 @@ static inline void *get_tls_desc(uint32_t vcoreid)
 /* passing in the vcoreid, since it'll be in TLS of the caller */
 static inline void set_tls_desc(void *tls_desc, uint32_t vcoreid)
 {
-  /* Keep this technique in sync with sysdeps/ros/i386/tls.h */
-  segdesc_t tmp = SEG(STA_W, (uint32_t)tls_desc, 0xffffffff, 3);
-  __procdata.ldt[vcoreid] = tmp;
+       /* Keep this technique in sync with sysdeps/ros/i386/tls.h */
+       segdesc_t tmp = SEG(STA_W, (uint32_t)tls_desc, 0xffffffff, 3);
+       __procdata.ldt[vcoreid] = tmp;
+
+       /* GS is still the same (should be!), but it needs to be reloaded to force a
+        * re-read of the LDT. */
+       uint32_t gs = (vcoreid << 3) | 0x07;
+       asm volatile("movl %0,%%gs" : : "r" (gs) : "memory");
 
-  /* GS is still the same (should be!), but it needs to be reloaded to force a
-   * re-read of the LDT. */
-  uint32_t gs = (vcoreid << 3) | 0x07;
-  asm volatile("movl %0,%%gs" : : "r" (gs) : "memory");
+       __vcoreid = vcoreid;
 }
 
 // this is how we get our thread id on entry.
@@ -157,14 +161,6 @@ static inline void set_tls_desc(void *tls_desc, uint32_t vcoreid)
        temp; \
 })
 
-// The actual vcore_self() function is a global symbol that invokes this routine.
-static inline int
-__vcore_id()
-{
-       // TODO: use some kind of thread-local storage to speed this up!
-       return (int)ros_syscall(SYS_getvcoreid,0,0,0,0,0);
-}
-
 /* For debugging. */
 #include <rstdio.h>
 static __inline void print_trapframe(struct user_trapframe *tf)
index b10ba83..c54281a 100644 (file)
@@ -8,6 +8,8 @@
 #include <ros/procdata.h>
 #include <assert.h>
 
+extern __thread int __vcoreid;
+
 /* Feel free to ignore vcoreid.  It helps x86 to avoid a call to
  * sys_getvcoreid() if we pass it in. */
 static inline void *get_tls_desc(uint32_t vcoreid)
@@ -20,6 +22,7 @@ static inline void *get_tls_desc(uint32_t vcoreid)
 static inline void set_tls_desc(void *tls_desc, uint32_t vcoreid)
 {
        asm volatile ("mov %0,%%g7" : : "r"(tls_desc) : "memory");
+       __vcoreid = vcoreid;
 }
 
 /* Pops an ROS kernel-provided TF, reanabling notifications at the same time.
@@ -53,9 +56,6 @@ static inline void pop_ros_tf(struct user_trapframe *tf, uint32_t vcoreid)
        else
                assert(tf->gpr[7] == (uint32_t)get_tls_desc(vcoreid));
 
-       // don't clobber the vcore id!
-       tf->asr13 = vcoreid;
-
        vcpd->notif_enabled = true;
        if(vcpd->notif_pending)
                ros_syscall(SYS_self_notify,vcoreid,0,0,0,0);
@@ -71,7 +71,7 @@ static inline void save_ros_tf(struct user_trapframe *tf)
 {
        // just do it in the kernel.  since we need to flush windows anyway,
        // this isn't an egregious overhead.
-       asm volatile ("mov %0, %%o0; ta 5" : : "r"(tf) : "o0");
+       asm volatile ("mov %0, %%o0; ta 5" : : "r"(tf) : "o0","memory");
 }
 
 /* This assumes a user_tf looks like a regular kernel trapframe */
@@ -84,14 +84,10 @@ init_user_tf(struct user_trapframe *u_tf, uint32_t entry_pt, uint32_t stack_top)
        u_tf->npc = entry_pt + 4;
 }
 
-#define __vcore_id_on_entry (__vcore_id())
-
-static inline int
-__vcore_id()
-{
-       int id;
-       asm ("mov %%asr13,%0" : "=r"(id));
-       return id;
-}
+#define __vcore_id_on_entry \
+({ \
+       register int temp asm ("g6"); \
+       temp; \
+})
 
 #endif /* PARLIB_ARCH_VCORE_H */
index 096fccb..5ae6882 100644 (file)
@@ -140,7 +140,6 @@ size_t num_vcores()
 
 int vcore_id()
 {
-       // defined in ros/arch/vcore.h
-       return __vcore_id();
+       return __vcoreid;
 }