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