tech-kern archive

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

swapcontext vs libpthread, round 10



Here is the latest patch with various comments adressed. Some points
raised I did not change:

- Documenting uc_flags while it is not public API. I just say that it 
is implementation specific and should not be used. IMO documentation cannot 
hurt, especially since the field name suggests it is public API while it 
is not (it should have been _uc_flags).

- tests/lib/libc/sys/t_swapcontext tests a non public API. Yes, but since
the change touch a lot of MD bits without the possibility of testing 
first, having the test case to diagnose a problem could be of great help.

- Joerg think the whole approach is wrong and suggests a purely userland
implementation. IMO my changes does not prevent such a work in the future
and even makes it easier. We need a core decision here.

-- 
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 3 Sep 2012 16:03:59 -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        3 Sep 2012 16:04:20 -0000
@@ -43,11 +43,16 @@
        SYSCALL(getcontext)
 
        ldw     HPPA_FRAME_ARG(0)(%sp), %arg1
        ldw     HPPA_FRAME_ARG(1)(%sp), %arg0
-       stw     %r0, (_OFFSETOF_UC_GREGS + _REG_RET0 * SZREG)(%arg1)
+
+       ldw     HPPA_FRAME_CRP(%sp), %rp
        ldo     4(%rp), %r1
        stw     %r1, (_OFFSETOF_UC_GREGS + _REG_PCOQT * SZREG)(%arg1)
        stw     %rp, (_OFFSETOF_UC_GREGS + _REG_PCOQH * SZREG)(%arg1)
-       SYSCALL(setcontext)
+       bl      setcontext, %rp
+       stw     %r0, (_OFFSETOF_UC_GREGS + _REG_RET0 * SZREG)(%arg1)
+
+       ldw     HPPA_FRAME_CRP(%sp), %rp
+       bv,n    %r0(%rp)
 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     3 Sep 2012 16:04:20 -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        3 Sep 2012 16:04:20 -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   3 Sep 2012 16:04:20 -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       3 Sep 2012 16:04:20 -0000
@@ -48,9 +48,14 @@
        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
 
-       mov     %o3, %o0
-       mov     %o1, %g2                        ! optimize `return'
-       mov     SYS_setcontext|SYSCALL_G2RFLAG, %g1
-       t       ST_SYSCALL
-       ERROR()
+#ifdef PIC
+       PIC_PROLOGUE(%g1, %g2)                  ! %g1 = _GLOBAL_OFFSET_TABLE
+       set     _C_LABEL(setcontext), %g2
+       ld      [%g1 + %g2], %g1
+       jmp     %g1
+        mov    %o3, %o0
+#else
+       jmp     _C_LABEL(setcontext)
+        mov    %o3, %o0
+#endif
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     3 Sep 2012 16:04:20 -0000
@@ -49,9 +49,18 @@
        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
-       ERROR()
+#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
Index: lib/libc/include/extern.h
===================================================================
RCS file: /cvsroot/src/lib/libc/include/extern.h,v
retrieving revision 1.19
diff -U 4 -r1.19 extern.h
--- lib/libc/include/extern.h   19 Sep 2011 21:24:58 -0000      1.19
+++ lib/libc/include/extern.h   3 Sep 2012 16:04:20 -0000
@@ -24,8 +24,9 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <stdarg.h>
+#include <ucontext.h>
 
 __BEGIN_DECLS
 extern char *__minbrk;
 int __getcwd(char *, size_t);
@@ -66,5 +67,7 @@
 
 void   _malloc_prefork(void);
 void   _malloc_postfork(void);
 
+int    _sys_setcontext(const ucontext_t *);
+
 __END_DECLS
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   3 Sep 2012 16:04:20 -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   3 Sep 2012 16:04:21 -0000
@@ -36,14 +36,21 @@
 
 #include "pthread.h"
 #include "pthread_int.h"
 
+#include <string.h>
 #include <sys/lwpctl.h>
 
+#include "../libc/include/extern.h" /* for _sys_setcontext() */
+
+int    pthread_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,pthread_setcontext)
+
 int
 pthread_setspecific(pthread_key_t key, const void *value)
 {
        pthread_t self;
@@ -74,4 +81,17 @@
 {
 
        return pthread__self()->pt_lwpctl->lc_curcpu;
 }
+
+/*
+ * Override setcontext so that pthread private pointer is preserved
+ */
+int
+pthread_setcontext(const ucontext_t *ucp)
+{
+       ucontext_t uc;
+
+       (void)memcpy(&uc, ucp, sizeof(uc));
+       uc.uc_flags &= ~_UC_TLSBASE;
+       return _sys_setcontext(&uc);
+}
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   3 Sep 2012 16:04:22 -0000
@@ -46,15 +46,22 @@
 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, it should not be used by
+portable code. List of supported flags and their description can be found in
+.In sys/ucontext.h .
+.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      3 Sep 2012 16:04:22 -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   3 Sep 2012 16:04:22 -0000
@@ -92,9 +92,9 @@
        __fpregset_t    __fpregs;
 } mcontext_t;
 
 /* Machine-dependent uc_flags */
-#define _UC_UNIQUE     0x20    /* valid process-unique value in _REG_UNIQUE */
+#define _UC_TLSBASE    0x20    /* valid process-unique value in _REG_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 3 Sep 2012 16:04:23 -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      3 Sep 2012 16:04:23 -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     3 Sep 2012 16:04:23 -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      3 Sep 2012 16:04:23 -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,10 @@
                error = cpu_mcontext_validate(l, mcp);
                if (error)
                        return error;
 
-               tf->tf_gbr    = gr[_REG_GBR];
+               /* done in lwp_setprivate */
+               /* tf->tf_gbr    = gr[_REG_GBR];  */
                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 +488,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   3 Sep 2012 16:04:23 -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      3 Sep 2012 16:04:24 -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,10 @@
                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];
-               tf->tf_global[7] = r[_REG_G7];
+               /* done in lwp_setprivate */
+               /* tf->tf_global[7] = r[_REG_G7]; */
 
                tf->tf_out[0] = r[_REG_O0];
                tf->tf_out[1] = r[_REG_O1];
                tf->tf_out[2] = r[_REG_O2];
@@ -757,9 +758,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 3 Sep 2012 16:04:24 -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  3 Sep 2012 16:04:24 -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,10 @@
                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];
-               tf->tf_global[7] = (uint64_t)gr[_REG_G7];
+               /* done in lwp_setprivate */
+               /* tf->tf_global[7] = (uint64_t)gr[_REG_G7]; */
                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 +2601,11 @@
                tf->tf_out[7]    = (uint64_t)gr[_REG_O7];
                /* %asi restored above; %fprs not yet supported. */
 
                /* XXX mcp->__gwins */
+
+               if (flags & _UC_TLSBASE)
+                       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 3 Sep 2012 16:04:24 -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,10 @@
                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];
-               tf->tf_global[7] = (uint64_t)gr[_REG32_G7];
+               /* done in lwp_setprivate */
+               /* tf->tf_global[7] = (uint64_t)gr[_REG32_G7]; */
                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 +1197,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)
+                       lwp_setprivate(l, (void *)(uintptr_t)gr[_REG32_G7]);
 
                /* XXX mcp->__gwins */
        }
 
@@ -1280,13 +1282,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  3 Sep 2012 16:04:25 -0000
@@ -56,23 +56,50 @@
 #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_SETSTACK    0x00010000 (many ports) and 0x00020000 (arm)
- *     _UC_CLRSTACK    0x00020000 (many ports) and 0x00040000 (arm)
- *     _UC_POWERPC_VEC 0x00010000 (powerpc)
- *     _UC_M68K_UC_USER 0x40000000 (m68k)
- *     _UC_UNIQUE      0x00000020 (alpha)
- *     _UC_ARM_VFP     0x00010000 (arm)
- *     _UC_VM          0x00040000 (i386)
- *     _UC_FXSAVE      0x00000020 (i386)
- *
  * if your port needs more MD bits, please try to choose bits from _UC_MD
  * first, rather than picking random unused bits.
+ *
+ * _UC_MD details
+ *
+ *     _UC_TLSBASE     Context contains valid pthread private pointer 
+ *                     All ports must define this MD flag
+ *                     0x00040000      hppa, mips
+ *                     0x00000020      alpha
+ *                     0x00080000      all other ports
+ *
+ *     _UC_SETSTACK    Context uses signal stack
+ *                     0x00020000      arm
+ *                     [undefined]     alpha, powerpc and vax
+ *                     0x00010000      other ports
+ *
+ *     _UC_CLRSTACK    Context does not use signal stack
+ *                     0x00040000      arm
+ *                     [undefined]     alpha, powerpc and vax
+ *                     0x00020000      other ports
+ *
+ *     _UC_POWERPC_VEC Context does not use signal stack
+ *                     0x00010000      powerpc only
+ *
+ *     _UC_POWERPC_SPE Context contains valid SPE context
+ *                     0x00020000      powerpc only
+ *
+ *     _UC_M68K_UC_USER Used by m68k machdep code, but undocumented
+ *                     0x40000000      m68k only
+ *
+ *     _UC_ARM_VFP     Unused
+ *                     0x00010000      arm only
+ *
+ *     _UC_VM          Context contains valid virtual 8086 context
+ *                     0x00040000      i386, amd64 only
+ *
+ *     _UC_FXSAVE      Context contains FPU context in that 
+ *                     is in FXSAVE format in XMM space 
+ *                     0x00000020      i386, amd64 only
  */
 
 #ifdef _KERNEL
 struct lwp;
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 3 Sep 2012 16:04:25 -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       3 Sep 2012 16:04:25 -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/libpthread/t_swapcontext.c.orig   1970-01-01 01:00:00.000000000 
+0100
+++ tests/lib/libpthread/t_swapcontext.c        2012-08-29 17:51:25.000000000 
+0200
@@ -0,0 +1,111 @@
+/* $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");
+
+       /* NOTREACHED */
+       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