tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: [PATCH] swapcontext vs pthread, round 4



On Sun, Aug 26, 2012 at 01:46:06AM +0000, Emmanuel Dreyfus wrote:
> Here is the patch so far, with previous suggestions integrated
Undated with the missing bit in libpthread

-- 
Emmanuel Dreyfus
manu%netbsd.org@localhost
Index: distrib/sets/lists/tests/mi
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/tests/mi,v
retrieving revision 1.480
diff -U 4 -r1.480 mi
--- distrib/sets/lists/tests/mi 23 Jul 2012 04:21:39 -0000      1.480
+++ distrib/sets/lists/tests/mi 26 Aug 2012 04:57:21 -0000
@@ -571,8 +571,9 @@
 ./usr/libdata/debug/usr/tests/lib/libc/sys/t_sigaction.debug           
tests-lib-debug         debug,atf
 ./usr/libdata/debug/usr/tests/lib/libc/sys/t_sigqueue.debug            
tests-lib-debug         debug,atf
 ./usr/libdata/debug/usr/tests/lib/libc/sys/t_socketpair.debug          
tests-lib-debug         debug,atf
 ./usr/libdata/debug/usr/tests/lib/libc/sys/t_stat.debug                        
tests-lib-debug         debug,atf
+./usr/libdata/debug/usr/tests/lib/libc/sys/t_swapcontext.debug         
tests-lib-debug         debug,atf
 ./usr/libdata/debug/usr/tests/lib/libc/sys/t_timer_create.debug                
tests-lib-debug         debug,atf
 ./usr/libdata/debug/usr/tests/lib/libc/sys/t_truncate.debug            
tests-lib-debug         debug,atf
 ./usr/libdata/debug/usr/tests/lib/libc/sys/t_ucontext.debug            
tests-lib-debug         debug,atf
 ./usr/libdata/debug/usr/tests/lib/libc/sys/t_umask.debug               
tests-lib-debug         debug,atf
@@ -672,8 +673,9 @@
 ./usr/libdata/debug/usr/tests/lib/libpthread/t_sigsuspend.debug                
tests-lib-tests         debug,atf
 ./usr/libdata/debug/usr/tests/lib/libpthread/t_siglongjmp.debug                
tests-lib-tests         debug,atf
 ./usr/libdata/debug/usr/tests/lib/libpthread/t_sleep.debug             
tests-lib-tests         debug,atf
 ./usr/libdata/debug/usr/tests/lib/libpthread/t_status.debug            
tests-obsolete          obsolete
+./usr/libdata/debug/usr/tests/lib/libpthread/t_swapcontext.debug       
tests-lib-tests         debug,atf
 ./usr/libdata/debug/usr/tests/lib/librt                                        
tests-lib-debug
 ./usr/libdata/debug/usr/tests/lib/librt/t_sched.debug                  
tests-lib-debug         debug,atf
 ./usr/libdata/debug/usr/tests/lib/librt/t_sem.debug                    
tests-lib-debug         debug,atf
 ./usr/libdata/debug/usr/tests/lib/librumpclient                                
        tests-lib-debug
@@ -2478,8 +2480,9 @@
 ./usr/tests/lib/libc/sys/t_sigaction           tests-lib-tests         atf
 ./usr/tests/lib/libc/sys/t_sigqueue            tests-lib-tests         atf
 ./usr/tests/lib/libc/sys/t_socketpair          tests-lib-tests         atf
 ./usr/tests/lib/libc/sys/t_stat                        tests-lib-tests         
atf
+./usr/tests/lib/libc/sys/t_swapcontext         tests-lib-tests         atf
 ./usr/tests/lib/libc/sys/t_timer_create                tests-lib-tests         
atf
 ./usr/tests/lib/libc/sys/t_truncate            tests-lib-tests         atf
 ./usr/tests/lib/libc/sys/t_ucontext            tests-lib-tests         atf
 ./usr/tests/lib/libc/sys/t_umask               tests-lib-tests         atf
@@ -2706,8 +2709,9 @@
 ./usr/tests/lib/libpthread/t_sigsuspend                tests-lib-tests         
atf
 ./usr/tests/lib/libpthread/t_siglongjmp                tests-lib-tests         
atf
 ./usr/tests/lib/libpthread/t_sleep             tests-lib-tests         atf
 ./usr/tests/lib/libpthread/t_status            tests-obsolete          obsolete
+./usr/tests/lib/libpthread/t_swapcontext       tests-lib-tests         atf
 ./usr/tests/lib/librt                          tests-lib-tests         atf
 ./usr/tests/lib/librt/Atffile                  tests-lib-tests         atf
 ./usr/tests/lib/librt/t_sched                  tests-lib-tests         atf
 ./usr/tests/lib/librt/t_sem                    tests-lib-tests         atf
Index: lib/libc/arch/hppa/gen/swapcontext.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/hppa/gen/swapcontext.S,v
retrieving revision 1.4
diff -U 4 -r1.4 swapcontext.S
--- lib/libc/arch/hppa/gen/swapcontext.S        28 Apr 2008 20:22:56 -0000      
1.4
+++ lib/libc/arch/hppa/gen/swapcontext.S        26 Aug 2012 04:57:41 -0000
@@ -47,7 +47,15 @@
        stw     %r0, (_OFFSETOF_UC_GREGS + _REG_RET0 * SZREG)(%arg1)
        ldo     4(%rp), %r1
        stw     %r1, (_OFFSETOF_UC_GREGS + _REG_PCOQT * SZREG)(%arg1)
        stw     %rp, (_OFFSETOF_UC_GREGS + _REG_PCOQH * SZREG)(%arg1)
-       SYSCALL(setcontext)
+#ifdef PIC 
+       ldw     HPPA_FRAME_EDP(%sp), %r19 
+       addil   LT%_C_LABEL(setcontext), %r19
+       ldw     RT%_C_LABEL(setcontext)(%r1), %r1
+#else  
+       ldil    L%_C_LABEL(setcontext), %r1
+       ldo     R%_C_LABEL(setcontext)(%r1), %r1
+#endif
+       bv,n    %r0(%r1)
 EXIT(swapcontext)
        .end
Index: lib/libc/arch/mips/gen/_resumecontext.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/mips/gen/_resumecontext.S,v
retrieving revision 1.6
diff -U 4 -r1.6 _resumecontext.S
--- lib/libc/arch/mips/gen/_resumecontext.S     14 Dec 2009 01:07:42 -0000      
1.6
+++ lib/libc/arch/mips/gen/_resumecontext.S     26 Aug 2012 04:57:41 -0000
@@ -52,9 +52,9 @@
        SYSTRAP(getcontext)                             # get context
        PTR_L           a0, _OFFSETOF_UC_LINK(a0)       # linked context?
        beq             a0, zero, 1f                    #   nope, exit process
        nop
-       SYSTRAP(setcontext)                             #   yes, become it.
+       PIC_TAILCALL(setcontext)                        #   yes, become it.
        /* NOTREACHED (in theory) */
        li              a0, -1                          # failure, 
 1:
        SYSTRAP(exit)                                   # all hope is lost.
Index: lib/libc/arch/mips/gen/swapcontext.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/mips/gen/swapcontext.S,v
retrieving revision 1.4
diff -U 4 -r1.4 swapcontext.S
--- lib/libc/arch/mips/gen/swapcontext.S        14 Dec 2009 01:07:42 -0000      
1.4
+++ lib/libc/arch/mips/gen/swapcontext.S        26 Aug 2012 04:57:41 -0000
@@ -56,9 +56,9 @@
        REG_S           ra, _OFFSETOF_UC_GREGS_EPC(v1)
        REG_S           v0, _OFFSETOF_UC_GREGS_SP(v1)
        REG_EPILOGUE
 
-       SYSTRAP(setcontext)
+       PIC_TAILCALL(setcontext)
        /* NOTREACHED */
 1:
        PTR_ADDU        sp, sp, CALLFRAME_SIZ
        SETUP_GPX(t0);
Index: lib/libc/arch/powerpc64/gen/swapcontext.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/powerpc64/gen/swapcontext.S,v
retrieving revision 1.3
diff -U 4 -r1.3 swapcontext.S
--- lib/libc/arch/powerpc64/gen/swapcontext.S   28 Apr 2008 20:22:57 -0000      
1.3
+++ lib/libc/arch/powerpc64/gen/swapcontext.S   26 Aug 2012 04:57:41 -0000
@@ -51,10 +51,10 @@
        ld      %r0,SF_SZ+SF_LR(%r1)            # get LR back
        std     %r0,mc_off+34*8(%r11)   #       pc <- lr
        la      %r0,16(%r1)
        std     %r0,mc_off+1*8(%r11)            # adjust sp
-       ld      %r3,SF_PARAM+8(%r1)                     # load ucp
-       bl      .setcontext                     # setcontext(ucp)
+       ld      %r3,SF_PARAM+8(%r1)             # load ucp
+       bl      PIC_PLT(_C_LABEL(setcontext))   # setcontext(ucp)
        nop
 1:
        ld      %r0,SF_SZ+SF_LR(%r1)
        mtlr    %r0
Index: lib/libc/arch/sparc/gen/swapcontext.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/sparc/gen/swapcontext.S,v
retrieving revision 1.3
diff -U 4 -r1.3 swapcontext.S
--- lib/libc/arch/sparc/gen/swapcontext.S       28 Apr 2008 20:22:57 -0000      
1.3
+++ lib/libc/arch/sparc/gen/swapcontext.S       26 Aug 2012 04:57:41 -0000
@@ -48,9 +48,15 @@
        st      %o1, [%o2 + 40 + 2 * 4]         ! gr[_REG_nPC] = retaddr + 4
        add     %o7, 8, %o1
        st      %o1, [%o2 + 40 + 1 * 4]         ! gr[_REG_PC] = retaddr
 
+#ifdef PIC
+       PIC_PROLOGUE(%g1, %g2)                  ! %g1 = _GLOBAL_OFFSET_TABLE
+       set     _C_LABEL(_setjmp), %g2
+       ld      [%g1 + %g2], %g1
+       jmp     %g1
        mov     %o3, %o0
-       mov     %o1, %g2                        ! optimize `return'
-       mov     SYS_setcontext|SYSCALL_G2RFLAG, %g1
-       t       ST_SYSCALL
+#else
+       jmp     _C_LABEL(setcontext)
+       mov     %o3, %o0
+#endif
        ERROR()
Index: lib/libc/arch/sparc64/gen/swapcontext.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/sparc64/gen/swapcontext.S,v
retrieving revision 1.5
diff -U 4 -r1.5 swapcontext.S
--- lib/libc/arch/sparc64/gen/swapcontext.S     28 Mar 2011 11:19:13 -0000      
1.5
+++ lib/libc/arch/sparc64/gen/swapcontext.S     26 Aug 2012 04:57:41 -0000
@@ -49,9 +49,19 @@
        stx     %o1, [%o2 + 64 + 2 * 8]         /* gr[_REG_nPC] = retaddr + 4 */
        add     %o7, 8, %o1
        stx     %o1, [%o2 + 64 + 1 * 8]         /* gr[_REG_PC] = retaddr */
 
-       mov     %o3, %o0
-       mov     %o1, %g5                        /* optimize `return' */
-       mov     SYS_setcontext|SYSCALL_G5RFLAG, %g1
-       t       ST_SYSCALL
+#ifdef PIC
+       PIC_PROLOGUE(%g5,%o4)                   /* %g5 = _GLOBAL_OFFSET_TABLE */
+#ifdef BIGPIC
+       set     _C_LABEL(setcontext),   %o6
+       ldx     [%g5+%o6],      %o5
+#else
+       ldx     [%g5+_C_LABEL(setcontext)],     %o5
+#endif
+       jmp     %o5
+       mov     %o3,    %o0
+#else
+       ba,a    _C_LABEL(setcontext)
+       mov     %o3,    %o0
+#endif
        ERROR()
Index: lib/libc/sys/Makefile.inc
===================================================================
RCS file: /cvsroot/src/lib/libc/sys/Makefile.inc,v
retrieving revision 1.215
diff -U 4 -r1.215 Makefile.inc
--- lib/libc/sys/Makefile.inc   22 Jun 2012 18:28:38 -0000      1.215
+++ lib/libc/sys/Makefile.inc   26 Aug 2012 04:57:41 -0000
@@ -119,9 +119,9 @@
        __quotactl.S \
        rasctl.S readlinkat.S reboot.S recvfrom.S recvmmsg.S recvmsg.S rename.S 
\
                renameat.S revoke.S rmdir.S \
        semconfig.S semget.S semop.S \
-               sendmmsg.S sendmsg.S sendto.S setegid.S setcontext.S seteuid.S \
+               sendmmsg.S sendmsg.S sendto.S setegid.S seteuid.S \
                setgid.S setgroups.S __setitimer50.S __setlogin.S setpgid.S \
                setpriority.S \
                setregid.S setreuid.S setrlimit.S setsid.S setsockopt.S \
                setuid.S __shmctl50.S shmdt.S shmget.S shutdown.S \
@@ -155,9 +155,9 @@
        msgrcv.S msgsnd.S __msync13.S  __nanosleep50.S open.S poll.S \
        __pollts50.S __pselect50.S read.S readlink.S \
        readv.S _sched_setparam.S _sched_getparam.S _sched_setaffinity.S \
        _sched_getaffinity.S sched_yield.S \
-       __select50.S __sigprocmask14.S __sigsuspend14.S sysarch.S \
+       __select50.S setcontext.S __sigprocmask14.S __sigsuspend14.S sysarch.S \
        __wait450.S write.S writev.S
 
 NOERR= getegid.S geteuid.S getgid.S getpid.S getppid.S getuid.S \
        issetugid.S posix_spawn.S sync.S __posix_fadvise50.S
Index: lib/libpthread/pthread_specific.c
===================================================================
RCS file: /cvsroot/src/lib/libpthread/pthread_specific.c,v
retrieving revision 1.21
diff -U 4 -r1.21 pthread_specific.c
--- lib/libpthread/pthread_specific.c   23 Jun 2008 10:38:39 -0000      1.21
+++ lib/libpthread/pthread_specific.c   26 Aug 2012 04:57:41 -0000
@@ -36,13 +36,17 @@
 
 #include "pthread.h"
 #include "pthread_int.h"
 
+#include <ucontext.h>
 #include <sys/lwpctl.h>
 
+int    _setcontext(const ucontext_t *);
+
 __strong_alias(__libc_thr_setspecific,pthread_setspecific)
 __strong_alias(__libc_thr_getspecific,pthread_getspecific)
 __strong_alias(__libc_thr_curcpu,pthread_curcpu_np)
+__strong_alias(_setcontext, setcontext)
 
 int
 pthread_setspecific(pthread_key_t key, const void *value)
 {
@@ -74,4 +78,14 @@
 {
 
        return pthread__self()->pt_lwpctl->lc_curcpu;
 }
+
+/*
+ * Override setcontext so that pthread private pointer is preserved
+ */
+int
+setcontext(const ucontext_t *ucp)
+{
+       ((ucontext_t *)__UNCONST(ucp))->uc_flags &= ~_UC_TLSBASE;
+       return _setcontext(ucp);
+}
Index: share/man/man2/ucontext.2
===================================================================
RCS file: /cvsroot/src/share/man/man2/ucontext.2,v
retrieving revision 1.6
diff -U 4 -r1.6 ucontext.2
--- share/man/man2/ucontext.2   29 Apr 2010 06:07:35 -0000      1.6
+++ share/man/man2/ucontext.2   26 Aug 2012 04:57:42 -0000
@@ -46,15 +46,21 @@
 The
 .Vt ucontext_t
 structure includes the following members:
 .Bd -literal -offset indent
-ucontext_t *uc_link
-sigset_t    uc_sigmask
-stack_t     uc_stack
-mcontext_t  uc_mcontext
+unsigned int uc_flags
+ucontext_t  *uc_link
+sigset_t     uc_sigmask
+stack_t      uc_stack
+mcontext_t   uc_mcontext
 .Ed
 .Pp
 The
+.Fa uc_flags
+member contains implementation-specific flags. Portable code should not
+use it. 
+.Pp
+The
 .Fa uc_link
 member points to the context that will be resumed after the function
 specified when modifying a context using
 .Xr makecontext 3
Index: sys/arch/alpha/alpha/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/alpha/machdep.c,v
retrieving revision 1.340
diff -U 4 -r1.340 machdep.c
--- sys/arch/alpha/alpha/machdep.c      13 Jun 2012 17:13:41 -0000      1.340
+++ sys/arch/alpha/alpha/machdep.c      26 Aug 2012 04:57:42 -0000
@@ -1793,9 +1793,9 @@
        if ((ras_pc = (__greg_t)ras_lookup(l->l_proc,
            (void *) gr[_REG_PC])) != -1)
                gr[_REG_PC] = ras_pc;
 
-       *flags |= _UC_CPU | _UC_UNIQUE;
+       *flags |= _UC_CPU | _UC_TLSBASE;
 
        /* Save floating point register context, if any, and copy it. */
        if (fpu_used_p(l)) {
                fpu_save();
@@ -1840,9 +1840,9 @@
                        pcb->pcb_hw.apcb_usp = gr[_REG_SP];
                frame->tf_regs[FRAME_PC] = gr[_REG_PC];
                frame->tf_regs[FRAME_PS] = gr[_REG_PS];
        }
-       if (flags & _UC_UNIQUE)
+       if (flags & _UC_TLSBASE)
                lwp_setprivate(l, (void *)(uintptr_t)gr[_REG_UNIQUE]);
        /* Restore floating point register context, if any. */
        if (flags & _UC_FPU) {
                /* If we have an FP register context, get rid of it. */
Index: sys/arch/alpha/include/mcontext.h
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/include/mcontext.h,v
retrieving revision 1.7
diff -U 4 -r1.7 mcontext.h
--- sys/arch/alpha/include/mcontext.h   25 Feb 2011 14:07:12 -0000      1.7
+++ sys/arch/alpha/include/mcontext.h   26 Aug 2012 04:57:42 -0000
@@ -93,8 +93,9 @@
 } mcontext_t;
 
 /* Machine-dependent uc_flags */
 #define _UC_UNIQUE     0x20    /* valid process-unique value in _REG_UNIQUE */
+#define _UC_TLSBASE    0x20    /* synonym of _UC_UNIQUE */
 
 #define _UC_MACHINE_SP(uc)     ((uc)->uc_mcontext.__gregs[_REG_SP])
 #define _UC_MACHINE_PC(uc)     ((uc)->uc_mcontext.__gregs[_REG_PC])
 #define _UC_MACHINE_INTRV(uc)  ((uc)->uc_mcontext.__gregs[_REG_V0])
Index: sys/arch/powerpc/include/mcontext.h
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/include/mcontext.h,v
retrieving revision 1.13
diff -U 4 -r1.13 mcontext.h
--- sys/arch/powerpc/include/mcontext.h 12 Mar 2011 07:38:16 -0000      1.13
+++ sys/arch/powerpc/include/mcontext.h 26 Aug 2012 04:57:44 -0000
@@ -114,8 +114,9 @@
 
 /* Machine-dependent uc_flags */
 #define        _UC_POWERPC_VEC 0x00010000      /* Vector Register File valid */
 #define        _UC_POWERPC_SPE 0x00020000      /* Vector Register File valid */
+#define        _UC_TLSBASE     0x00080000      /* thread context valid */
 
 #define _UC_MACHINE_SP(uc)     ((uc)->uc_mcontext.__gregs[_REG_R1])
 #define _UC_MACHINE_PC(uc)     ((uc)->uc_mcontext.__gregs[_REG_PC])
 #define _UC_MACHINE_INTRV(uc)  ((uc)->uc_mcontext.__gregs[_REG_R3])
Index: sys/arch/powerpc/powerpc/sig_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/powerpc/sig_machdep.c,v
retrieving revision 1.42
diff -U 4 -r1.42 sig_machdep.c
--- sys/arch/powerpc/powerpc/sig_machdep.c      21 May 2012 14:15:18 -0000      
1.42
+++ sys/arch/powerpc/powerpc/sig_machdep.c      26 Aug 2012 04:57:44 -0000
@@ -170,9 +170,9 @@
 #else
        gr[_REG_MQ]  = 0;
 #endif
 
-       *flagp |= _UC_CPU;
+       *flagp |= (_UC_CPU|_UC_TLSBASE);
 
 #ifdef PPC_HAVE_FPU
        /* Save FPU context, if any. */
        if (!fpu_save_to_mcontext(l, mcp, flagp))
@@ -196,8 +196,9 @@
 cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags)
 {
        struct trapframe * const tf = l->l_md.md_utf;
        const __greg_t * const gr = mcp->__gregs;
+       __greg_t saved_r2;
        int error;
 
        /* Restore GPR context, if any. */
        if (flags & _UC_CPU) {
@@ -213,8 +214,9 @@
                pcb->pcb_flags &= ~(PCB_FE0|PCB_FE1);
                pcb->pcb_flags |= gr[_REG_MSR] & (PCB_FE0|PCB_FE1);
 #endif
 
+               saved_r2 = tf->tf_fixreg[_REG_R2];
                (void)memcpy(&tf->tf_fixreg, gr, 32 * sizeof (gr[0]));
                tf->tf_cr   = gr[_REG_CR];
                tf->tf_lr   = gr[_REG_LR];
                tf->tf_srr0 = gr[_REG_PC];
@@ -228,8 +230,11 @@
                tf->tf_xer  = gr[_REG_XER];
 #ifdef PPC_OEA
                tf->tf_mq = gr[_REG_MQ];
 #endif
+
+               if (!(flags & _UC_TLSBASE))
+                       tf->tf_fixreg[_REG_R2] = saved_r2;
        }
 
 #ifdef PPC_HAVE_FPU
        /* Restore FPU context, if any. */
Index: sys/arch/sh3/include/mcontext.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/include/mcontext.h,v
retrieving revision 1.9
diff -U 4 -r1.9 mcontext.h
--- sys/arch/sh3/include/mcontext.h     25 Feb 2011 14:07:13 -0000      1.9
+++ sys/arch/sh3/include/mcontext.h     26 Aug 2012 04:57:44 -0000
@@ -91,8 +91,9 @@
  * Machine dependent uc_flags
  */
 #define        _UC_SETSTACK            0x10000
 #define        _UC_CLRSTACK            0x20000
+#define        _UC_TLSBASE             0x80000
 
 static __inline void *
 __lwp_getprivate_fast(void)
 {
Index: sys/arch/sh3/sh3/sh3_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/sh3/sh3_machdep.c,v
retrieving revision 1.100
diff -U 4 -r1.100 sh3_machdep.c
--- sys/arch/sh3/sh3/sh3_machdep.c      8 Jul 2012 20:14:12 -0000       1.100
+++ sys/arch/sh3/sh3/sh3_machdep.c      26 Aug 2012 04:57:44 -0000
@@ -431,9 +431,9 @@
        if ((ras_pc = (__greg_t)ras_lookup(l->l_proc,
            (void *) gr[_REG_PC])) != -1)
                gr[_REG_PC] = ras_pc;
 
-       *flags |= _UC_CPU;
+       *flags |= (_UC_CPU|_UC_TLSBASE);
 
        /* FPU context is currently not handled by the kernel. */
        memset(&mcp->__fpregs, 0, sizeof (mcp->__fpregs));
 }
@@ -464,9 +464,11 @@
                error = cpu_mcontext_validate(l, mcp);
                if (error)
                        return error;
 
+#if notanymore /* done in lwp_setprivate */
                tf->tf_gbr    = gr[_REG_GBR];
+#endif
                tf->tf_spc    = gr[_REG_PC];
                tf->tf_ssr    = gr[_REG_SR];
                tf->tf_macl   = gr[_REG_MACL];
                tf->tf_mach   = gr[_REG_MACH];
@@ -487,9 +489,10 @@
                tf->tf_r1     = gr[_REG_R1];
                tf->tf_r0     = gr[_REG_R0];
                tf->tf_r15    = gr[_REG_R15];
 
-               lwp_setprivate(l, (void *)(uintptr_t)gr[_REG_GBR]);
+               if (flags & _UC_TLSBASE)
+                       lwp_setprivate(l, (void *)(uintptr_t)gr[_REG_GBR]);
        }
 
 #if 0
        /* XXX: FPU context is currently not handled by the kernel. */
Index: sys/arch/sparc/include/mcontext.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/include/mcontext.h,v
retrieving revision 1.12
diff -U 4 -r1.12 mcontext.h
--- sys/arch/sparc/include/mcontext.h   25 Feb 2011 14:07:13 -0000      1.12
+++ sys/arch/sparc/include/mcontext.h   26 Aug 2012 04:57:44 -0000
@@ -33,8 +33,9 @@
 #define _SPARC_MCONTEXT_H_
 
 #define _UC_SETSTACK   0x00010000
 #define _UC_CLRSTACK   0x00020000
+#define _UC_TLSBASE    0x00080000
 
 /*
  * Layout of mcontext_t according the System V Application Binary Interface,
  * Edition 4.1, SPARC Processor ABI Supplement and updated for SPARC v9.
Index: sys/arch/sparc/sparc/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/sparc/machdep.c,v
retrieving revision 1.319
diff -U 4 -r1.319 machdep.c
--- sys/arch/sparc/sparc/machdep.c      21 May 2012 14:15:18 -0000      1.319
+++ sys/arch/sparc/sparc/machdep.c      26 Aug 2012 04:57:44 -0000
@@ -640,9 +640,9 @@
        r[_REG_O5] = tf->tf_out[5];
        r[_REG_O6] = tf->tf_out[6];
        r[_REG_O7] = tf->tf_out[7];
 
-       *flags |= _UC_CPU;
+       *flags |= (_UC_CPU|_UC_TLSBASE);
 
 #ifdef FPU_CONTEXT
        /*
         * Get the floating point registers
@@ -746,9 +746,11 @@
                tf->tf_global[3] = r[_REG_G3];
                tf->tf_global[4] = r[_REG_G4];
                tf->tf_global[5] = r[_REG_G5];
                tf->tf_global[6] = r[_REG_G6];
+#if notanymore /* done in lwp_setprivate */
                tf->tf_global[7] = r[_REG_G7];
+#endif
 
                tf->tf_out[0] = r[_REG_O0];
                tf->tf_out[1] = r[_REG_O1];
                tf->tf_out[2] = r[_REG_O2];
@@ -757,9 +759,10 @@
                tf->tf_out[5] = r[_REG_O5];
                tf->tf_out[6] = r[_REG_O6];
                tf->tf_out[7] = r[_REG_O7];
 
-               lwp_setprivate(l, (void *)(uintptr_t)r[_REG_G7]);
+               if (flags & _UC_TLSBASE)
+                       lwp_setprivate(l, (void *)(uintptr_t)r[_REG_G7]);
        }
 
 #ifdef FPU_CONTEXT
        if (flags & _UC_FPU) {
Index: sys/arch/sparc64/include/mcontext.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/include/mcontext.h,v
retrieving revision 1.8
diff -U 4 -r1.8 mcontext.h
--- sys/arch/sparc64/include/mcontext.h 16 Mar 2006 16:05:53 -0000      1.8
+++ sys/arch/sparc64/include/mcontext.h 26 Aug 2012 04:57:44 -0000
@@ -73,6 +73,7 @@
 } mcontext32_t;
 
 #define        _UC_SETSTACK    0x00010000
 #define        _UC_CLRSTACK    0x00020000
+#define        _UC_TLSBASE     0x00080000
 
 #endif /* _SPARC64_MCONTEXT_H_ */
Index: sys/arch/sparc64/sparc64/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/machdep.c,v
retrieving revision 1.267
diff -U 4 -r1.267 machdep.c
--- sys/arch/sparc64/sparc64/machdep.c  21 May 2012 14:15:18 -0000      1.267
+++ sys/arch/sparc64/sparc64/machdep.c  26 Aug 2012 04:57:44 -0000
@@ -2499,9 +2499,9 @@
                gr[_REG_PC] = ras_pc;
                gr[_REG_nPC] = ras_pc + 4;
        }
 
-       *flags |= _UC_CPU;
+       *flags |= (_UC_CPU|_UC_TLSBASE);
 
        mcp->__gwins = NULL;
 
 
@@ -2588,9 +2588,11 @@
                tf->tf_global[3] = (uint64_t)gr[_REG_G3];
                tf->tf_global[4] = (uint64_t)gr[_REG_G4];
                tf->tf_global[5] = (uint64_t)gr[_REG_G5];
                tf->tf_global[6] = (uint64_t)gr[_REG_G6];
+#if notanymore /* done in cpu_lwp_setprivate */
                tf->tf_global[7] = (uint64_t)gr[_REG_G7];
+#endif
                tf->tf_out[0]    = (uint64_t)gr[_REG_O0];
                tf->tf_out[1]    = (uint64_t)gr[_REG_O1];
                tf->tf_out[2]    = (uint64_t)gr[_REG_O2];
                tf->tf_out[3]    = (uint64_t)gr[_REG_O3];
@@ -2600,8 +2602,11 @@
                tf->tf_out[7]    = (uint64_t)gr[_REG_O7];
                /* %asi restored above; %fprs not yet supported. */
 
                /* XXX mcp->__gwins */
+
+               if (flags & _UC_TLSBASE)
+                       cpu_lwp_setprivate(l, (void *)(uintptr_t)gr[_REG_G7]);
        }
 
        /* Restore FP register context, if any. */
        if ((flags & _UC_FPU) != 0 && mcp->__fpregs.__fpu_en != 0) {
Index: sys/arch/sparc64/sparc64/netbsd32_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/netbsd32_machdep.c,v
retrieving revision 1.98
diff -U 4 -r1.98 netbsd32_machdep.c
--- sys/arch/sparc64/sparc64/netbsd32_machdep.c 21 May 2012 14:15:18 -0000      
1.98
+++ sys/arch/sparc64/sparc64/netbsd32_machdep.c 26 Aug 2012 04:57:44 -0000
@@ -776,9 +776,9 @@
        gr[_REG_O4]  = tf->tf_out[4];
        gr[_REG_O5]  = tf->tf_out[5];
        gr[_REG_O6]  = tf->tf_out[6];
        gr[_REG_O7]  = tf->tf_out[7];
-       *flags |= _UC_CPU;
+       *flags |= (_UC_CPU|_UC_TLSBASE);
 
        mcp->__gwins = 0;
 
 
@@ -1185,9 +1185,11 @@
                tf->tf_global[3] = (uint64_t)gr[_REG32_G3];
                tf->tf_global[4] = (uint64_t)gr[_REG32_G4];
                tf->tf_global[5] = (uint64_t)gr[_REG32_G5];
                tf->tf_global[6] = (uint64_t)gr[_REG32_G6];
+#if notanymore /* done in cpu_lwp_setprivate */
                tf->tf_global[7] = (uint64_t)gr[_REG32_G7];
+#endif
                tf->tf_out[0]    = (uint64_t)gr[_REG32_O0];
                tf->tf_out[1]    = (uint64_t)gr[_REG32_O1];
                tf->tf_out[2]    = (uint64_t)gr[_REG32_O2];
                tf->tf_out[3]    = (uint64_t)gr[_REG32_O3];
@@ -1196,9 +1198,10 @@
                tf->tf_out[6]    = (uint64_t)gr[_REG32_O6];
                tf->tf_out[7]    = (uint64_t)gr[_REG32_O7];
                /* %asi restored above; %fprs not yet supported. */
 
-               lwp_setprivate(l, (void *)(uintptr_t)gr[_REG_G7]);
+               if (flags & _UC_TLSBASE)
+                       cpu_lwp_setprivate(l, (void *)(uintptr_t)gr[_REG32_G7]);
 
                /* XXX mcp->__gwins */
        }
 
@@ -1280,13 +1283,13 @@
        gr[_REG32_O4]  = tf->tf_out[4];
        gr[_REG32_O5]  = tf->tf_out[5];
        gr[_REG32_O6]  = tf->tf_out[6];
        gr[_REG32_O7]  = tf->tf_out[7];
-       *flags |= _UC_CPU;
+       *flags |= (_UC_CPU|_UC_TLSBASE);
 
        mcp->__gwins = 0;
        mcp->__xrs.__xrs_id = 0;        /* Solaris extension? */
-       *flags |= _UC_CPU;
+       *flags |= (_UC_CPU|_UC_TLSBASE);
 
        /* Save FP register context, if any. */
        if (l->l_md.md_fpstate != NULL) {
 #ifdef notyet
Index: sys/sys/ucontext.h
===================================================================
RCS file: /cvsroot/src/sys/sys/ucontext.h,v
retrieving revision 1.16
diff -U 4 -r1.16 ucontext.h
--- sys/sys/ucontext.h  21 May 2012 14:15:19 -0000      1.16
+++ sys/sys/ucontext.h  26 Aug 2012 04:57:46 -0000
@@ -56,15 +56,20 @@
 #define _UC_SIGMASK    0x01            /* valid uc_sigmask */
 #define _UC_STACK      0x02            /* valid uc_stack */
 #define _UC_CPU                0x04            /* valid GPR context in 
uc_mcontext */
 #define _UC_FPU                0x08            /* valid FPU context in 
uc_mcontext */
-#define        _UC_MD          0x40070020      /* MD bits.  see below */
+#define        _UC_MD          0x400f0020      /* MD bits.  see below */
 
 /*
  * _UC_MD includes:
+ *     _UC_TLSBASE     0x00080000 (all ports except hppa, mips, alpha)
+ *                     0x00040000 (hppa, mips)
+ *                     0x00000020 (alpha)
+ *     _UC_UNIQUE      0x00000020 synonym of _UC_TLSBASE on alpha
  *     _UC_SETSTACK    0x00010000 (many ports) and 0x00020000 (arm)
  *     _UC_CLRSTACK    0x00020000 (many ports) and 0x00040000 (arm)
  *     _UC_POWERPC_VEC 0x00010000 (powerpc)
+ *     _UC_POWERPC_SPE 0x00020000 (powerpc)
  *     _UC_M68K_UC_USER 0x40000000 (m68k)
  *     _UC_UNIQUE      0x00000020 (alpha)
  *     _UC_ARM_VFP     0x00010000 (arm)
  *     _UC_VM          0x00040000 (i386)
Index: tests/lib/libc/sys/Makefile
===================================================================
RCS file: /cvsroot/src/tests/lib/libc/sys/Makefile,v
retrieving revision 1.26
diff -U 4 -r1.26 Makefile
--- tests/lib/libc/sys/Makefile 22 Jun 2012 18:45:23 -0000      1.26
+++ tests/lib/libc/sys/Makefile 26 Aug 2012 04:57:46 -0000
@@ -54,8 +54,9 @@
 TESTS_C+=              t_setuid
 TESTS_C+=              t_sigaction
 TESTS_C+=              t_sigqueue
 TESTS_C+=              t_socketpair
+TESTS_C+=              t_swapcontext
 TESTS_C+=              t_stat
 TESTS_C+=              t_timer_create
 TESTS_C+=              t_truncate
 TESTS_C+=              t_ucontext
Index: tests/lib/libpthread/Makefile
===================================================================
RCS file: /cvsroot/src/tests/lib/libpthread/Makefile,v
retrieving revision 1.7
diff -U 4 -r1.7 Makefile
--- tests/lib/libpthread/Makefile       6 Apr 2011 16:04:16 -0000       1.7
+++ tests/lib/libpthread/Makefile       26 Aug 2012 04:57:46 -0000
@@ -34,8 +34,9 @@
 TESTS_C+=      t_sigmask
 TESTS_C+=      t_sigsuspend
 TESTS_C+=      t_siglongjmp
 TESTS_C+=      t_sleep
+TESTS_C+=      t_swapcontext
 
 LDADD.t_sem+=  -lrt
 
 BINDIR=                ${TESTSDIR}
--- tests/lib/libc/sys/t_swapcontext.c.orig     1970-01-01 01:00:00.000000000 
+0100
+++ tests/lib/libc/sys/t_swapcontext.c  2012-08-22 10:56:34.000000000 +0200
@@ -0,0 +1,133 @@
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 2012 Emmanuel Dreyfus. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD");
+
+#include <ucontext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <lwp.h>
+
+#include <atf-c.h>
+
+#define STACKSIZE 65536
+
+char stack[STACKSIZE];
+ucontext_t nctx;
+ucontext_t octx;
+void *otls;
+void *ntls;
+int val1, val2;
+int alter_tlsbase;
+
+/* ARGSUSED0 */
+static void
+swapfunc(void *arg)
+{
+       ntls = _lwp_getprivate();
+       printf("after swapcontext TLS pointer = %p\n", ntls);
+
+       if (alter_tlsbase) {
+               ATF_REQUIRE_EQ(ntls, &val1);
+               printf("TLS pointer modified by swapcontext()\n");
+       } else {
+               ATF_REQUIRE_EQ(ntls, &val2);
+               printf("TLS pointer left untouched by swapcontext()\n");
+       }
+
+       /* Go back in main */
+       ATF_REQUIRE(swapcontext(&nctx, &octx));
+
+       /* NOTREACHED */
+       return;
+}
+
+static void
+mainfunc(void)
+{
+       printf("Testing if swapcontext() alters TLS pointer if _UC_TLSBASE "
+              "is %s\n", (alter_tlsbase) ? "left set" : "cleared");
+
+       _lwp_setprivate(&val1);
+       printf("before swapcontext TLS pointer = %p\n", &val1);
+
+       ATF_REQUIRE(getcontext(&nctx) == 0);
+
+       nctx.uc_stack.ss_sp = stack;
+       nctx.uc_stack.ss_size = sizeof(stack);
+
+#ifndef _UC_TLSBASE
+       ATF_REQUIRE_MSG(0, "_UC_TLSBASE is not defined");
+#else /* _UC_TLSBASE */
+       ATF_REQUIRE(nctx.uc_flags & _UC_TLSBASE);
+       if (!alter_tlsbase)
+               nctx.uc_flags &= ~_UC_TLSBASE;
+#endif /* _UC_TLSBASE */
+       
+       makecontext(&nctx, (void *)*swapfunc, 0);
+       
+       _lwp_setprivate(&val2);
+       otls = _lwp_getprivate();
+       printf("before swapcontext TLS pointer = %p\n", otls);
+       ATF_REQUIRE(swapcontext(&octx, &nctx) == 0);
+
+       printf("Test completed\n");
+}
+
+
+ATF_TC(swapcontext1);
+ATF_TC_HEAD(swapcontext1, tc)
+{
+       atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() can let "
+           "TLS pointer untouched");
+}
+ATF_TC_BODY(swapcontext1, tc)
+{
+       alter_tlsbase = 0;
+       mainfunc();
+}
+
+ATF_TC(swapcontext2);
+ATF_TC_HEAD(swapcontext2, tc)
+{
+       atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() can "
+           "modify TLS pointer");
+}
+ATF_TC_BODY(swapcontext2, tc)
+{
+       alter_tlsbase = 1;
+       mainfunc();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+       ATF_TP_ADD_TC(tp, swapcontext1);
+       ATF_TP_ADD_TC(tp, swapcontext2);
+
+       return atf_no_error();
+}
--- tests/lib/libc/sys/t_swapcontext.c.orig     1970-01-01 01:00:00.000000000 
+0100
+++ tests/lib/libpthread/t_swapcontext.c        2012-08-22 10:46:13.000000000 
+0200
@@ -0,0 +1,110 @@
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 2012 Emmanuel Dreyfus. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD");
+
+#include <pthread.h>
+#include <ucontext.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+#define STACKSIZE 65536
+
+char stack[STACKSIZE];
+ucontext_t nctx;
+ucontext_t octx;
+void *oself;
+void *nself;
+int val1, val2;
+
+/* ARGSUSED0 */
+static void
+swapfunc(void *arg)
+{
+       /*
+        * If the test fails, we are very likely to crash 
+        * without the opportunity to report
+        */ 
+       nself = (void *)pthread_self();
+       printf("after swapcontext self = %p\n", nself);
+
+       ATF_REQUIRE_EQ(oself, nself);
+       printf("Test succeeded\n");
+
+       return;
+}
+
+/* ARGSUSED0 */
+static void *
+threadfunc(void *arg)
+{
+       nctx.uc_stack.ss_sp = stack;
+       nctx.uc_stack.ss_size = sizeof(stack);
+       
+       makecontext(&nctx, (void *)*swapfunc, 0);
+       
+       oself = (void *)pthread_self();
+       printf("before swapcontext self = %p\n", oself);
+       PTHREAD_REQUIRE(swapcontext(&octx, &nctx));
+
+       /* NOTREACHED */
+       return NULL;
+}
+
+
+ATF_TC(swapcontext1);
+ATF_TC_HEAD(swapcontext1, tc)
+{
+       atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() "
+           "alters pthread_self()");
+}
+ATF_TC_BODY(swapcontext1, tc)
+{
+       pthread_t thread;
+
+       oself = (void *)&val1;
+       nself = (void *)&val2;
+
+       printf("Testing if swapcontext() alters pthread_self()\n");
+
+       PTHREAD_REQUIRE(getcontext(&nctx));
+       PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc, NULL));
+       
+       return;
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+       ATF_TP_ADD_TC(tp, swapcontext1);
+
+       return atf_no_error();
+}


Home | Main Index | Thread Index | Old Index