summaryrefslogtreecommitdiff
path: root/lib/libpthread
diff options
context:
space:
mode:
authornathanw <nathanw@NetBSD.org>2003-06-26 01:45:31 +0000
committernathanw <nathanw@NetBSD.org>2003-06-26 01:45:31 +0000
commit9639eeaf5402c011f48282ba82e9d53e0f4a91ef (patch)
tree56d434a05cb67889c39c59682ad685cb425153be /lib/libpthread
parent487eb7e1931dc8d1b63f2d5260bb26885273333c (diff)
Adapt to pt_trapuc: change STACK_SWITCH to check for a value in pt_trapuc
and use it preferentially to a value in pt_uc, clearing it once on the new stack. Move stores into pt_uc back to before the stack switch; storing after the stack switch opened a one-instruction race condition where an upcall that had just started a chain could be preempted again, and would bomb when restarted due to its pt_uc not yet having been updated. Now that pt_trapuc is what the upcall code writes to, it is safe to store to pt_uc before switching stacks. Remove obsolete pt_sleepuc code.
Diffstat (limited to 'lib/libpthread')
-rw-r--r--lib/libpthread/arch/alpha/pthread_switch.S17
-rw-r--r--lib/libpthread/arch/arm/pthread_switch.S36
-rw-r--r--lib/libpthread/arch/i386/pthread_switch.S22
-rw-r--r--lib/libpthread/arch/m68k/pthread_switch.S19
-rw-r--r--lib/libpthread/arch/mips/pthread_switch.S20
-rw-r--r--lib/libpthread/arch/powerpc/pthread_switch.S33
-rw-r--r--lib/libpthread/arch/sparc/pthread_switch.S23
-rw-r--r--lib/libpthread/arch/sparc64/pthread_switch.S23
-rw-r--r--lib/libpthread/arch/x86_64/pthread_switch.S20
9 files changed, 89 insertions, 124 deletions
diff --git a/lib/libpthread/arch/alpha/pthread_switch.S b/lib/libpthread/arch/alpha/pthread_switch.S
index 9a29d68959e..a95a0ff94de 100644
--- a/lib/libpthread/arch/alpha/pthread_switch.S
+++ b/lib/libpthread/arch/alpha/pthread_switch.S
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_switch.S,v 1.3 2003/06/12 21:46:03 nathanw Exp $ */
+/* $NetBSD: pthread_switch.S,v 1.4 2003/06/26 01:45:31 nathanw Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -62,8 +62,11 @@
*/
#define STACK_SWITCH(pt,tmp) \
+ ldq tmp, PT_TRAPUC(pt) ; \
+ bne tmp, 1f ; \
ldq tmp, PT_UC(pt) ; \
- lda sp, -STACKSPACE(tmp)
+1: lda sp, -STACKSPACE(tmp) ; \
+ stq zero, PT_TRAPUC(pt)
NESTED(pthread__switch, 2, CONTEXTSIZE + 24, ra, 0, 0)
LDGP(pv)
@@ -84,10 +87,10 @@ NESTED(pthread__switch, 2, CONTEXTSIZE + 24, ra, 0, 0)
stq t1, (UC_GREGS + _REG_PC * 8)(t3)
lda t0, 24(sp)
+ stq t0, PT_UC(a0)
STACK_SWITCH(a1, t2)
- stq t0, PT_UC(a0)
mov t2, a0
CALL(_setcontext_u)
XNESTED(pthread__switch_return_point, 2)
@@ -146,10 +149,10 @@ NESTED(pthread__locked_switch, 3, CONTEXTSIZE + 32, ra, 0x00030000, 0)
stq t1, (UC_GREGS + _REG_PC * 8)(t3)
lda t0, 32(sp)
+ stq t0, PT_UC(a0)
STACK_SWITCH(a1, t2)
- stq t0, PT_UC(a0)
/* Check if the switcher was preempted and continued to here. */
ldq t0, PT_NEXT(a0)
beq t0, 1f
@@ -170,12 +173,6 @@ NESTED(pthread__locked_switch, 3, CONTEXTSIZE + 32, ra, 0x00030000, 0)
subl t4, 1, t4
stl t4, PT_SPINLOCKS(a0)
- /* Save the context we previously stored in PT_UC(a0);
- * that was overwritten when we were preempted and continued,
- * so we need to put it somewhere.
- */
- stq t3, PT_SLEEPUC(a0)
-
mov a1, a0
mov t0, a1
mov 1, a2
diff --git a/lib/libpthread/arch/arm/pthread_switch.S b/lib/libpthread/arch/arm/pthread_switch.S
index 5b2d30730c1..4120245cf72 100644
--- a/lib/libpthread/arch/arm/pthread_switch.S
+++ b/lib/libpthread/arch/arm/pthread_switch.S
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_switch.S,v 1.4 2003/06/12 21:46:04 nathanw Exp $ */
+/* $NetBSD: pthread_switch.S,v 1.5 2003/06/26 01:45:31 nathanw Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -53,10 +53,14 @@
* comment in the i386 pthread_switch.S file.
*/
-#define STACK_SWITCH(pt, tmp) \
+#define STACK_SWITCH(pt, tmp, z) \
+ ldr tmp, [pt, #(PT_TRAPUC)] ; \
+ teq tmp, #0x00000000 ; \
+ bne 1f ; \
ldr tmp, [pt, #(PT_UC)] ; \
- sub sp, tmp, #(STACKSPACE)
-
+1: sub sp, tmp, #(STACKSPACE) ; \
+ mov z, #00000000 ; \
+ str z, [pt, #(PT_TRAPUC)]
/*
* void
@@ -107,11 +111,11 @@ ENTRY(pthread__switch)
/* Get back r0-r2 */
ldmfd sp, {r0-r2}
- /* Side-effect: r4 = next->pt_uc */
- STACK_SWITCH(r1, r4)
-
str r5, [r0, #(PT_UC)] /* self->pt_uc = &context */
+ /* Side-effect: r4 = next->pt_uc */
+ STACK_SWITCH(r1, r4, r3)
+
/* NOTE: we can no longer recover registers stored on the stack */
mov r0, r4 /* r0 = next->pt_uc */
@@ -142,7 +146,7 @@ ENTRY_NP(pthread__switch_return_point)
*/
pthread__switch_away:
/* Side-effect: r3 = r1->pt_uc */
- STACK_SWITCH(r1, r3)
+ STACK_SWITCH(r1, r3, r14)
/*
* If we're invoked from the switch-to-next provisions of
@@ -178,7 +182,7 @@ ENTRY(pthread__upcall_switch)
str r3, [r1, #(PT_SPINLOCKS)]
/* Side-effect: r7 = next->pt_uc */
- STACK_SWITCH(r1, r7)
+ STACK_SWITCH(r1, r7, r2)
/* Check if the upcall code was preempted and continued to here. */
ldr r3, [r0, #(PT_NEXT)]
@@ -264,7 +268,6 @@ ENTRY(pthread__locked_switch)
str r3, [r1, #(PT_SPINLOCKS)]
mov r3, sp /* r3 = &context */
- str r3, [r0, #(PT_UC)] /* self->pt_uc = &context */
/* Save r0-r2, r4-r5, lr */
stmfd sp!, {r0-r2, r4-r5, lr}
@@ -291,13 +294,15 @@ ENTRY(pthread__locked_switch)
/* Edit the context to make it continue below, rather than here */
add r0, pc, #locked_return_point - . - 8
- str r0, [r3, #(_REG_PC)]
+ str r0, [r5, #(_REG_PC)]
/* Get back r0-r2 */
ldmfd sp, {r0-r2}
+ str r5, [r0, #(PT_UC)] /* self->pt_uc = &context */
+
/* Side-effect: r4 = next->pt_uc */
- STACK_SWITCH(r1, r4)
+ STACK_SWITCH(r1, r4, r3)
/* NOTE: we can no longer recover registers stored on the stack */
@@ -325,13 +330,6 @@ ENTRY(pthread__locked_switch)
sub r4, r4, #1
str r4, [r0, #(PT_SPINLOCKS)]
- /*
- * Save the context we previously stored in self->pt_uc; that
- * was overwritten when we were preempted and continued, so we
- * need to put it someplace.
- */
- str r5, [r0, #(PT_SLEEPUC)]
-
mov r0, r1 /* from = next */
mov r1, r3 /* to = self->pt_next */
mov r2, #0x00000001 /* decr-spinlocks = TRUE */
diff --git a/lib/libpthread/arch/i386/pthread_switch.S b/lib/libpthread/arch/i386/pthread_switch.S
index 633e5c06851..0b49c20d987 100644
--- a/lib/libpthread/arch/i386/pthread_switch.S
+++ b/lib/libpthread/arch/i386/pthread_switch.S
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_switch.S,v 1.4 2003/06/12 21:46:04 nathanw Exp $ */
+/* $NetBSD: pthread_switch.S,v 1.5 2003/06/26 01:45:32 nathanw Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -100,9 +100,12 @@
*/
#define STACK_SWITCH \
+ movl PT_TRAPUC(%ecx), %esi ; \
+ cmpl $0, %esi ; \
+ jne 1f ; \
movl PT_UC(%ecx), %esi ; \
- lea (-STACKSPACE)(%esi), %esp
-
+1: lea (-STACKSPACE)(%esi), %esp ; \
+ movl $0, PT_TRAPUC(%ecx)
/*
* void pthread__switch(pthread_t self, pthread_t next);
@@ -144,10 +147,10 @@ ENTRY(pthread__switch)
leal pthread__switch_return_point, %esi
#endif
movl %esi, UC_EIP(%edi)
+
+ movl %edi, PT_UC(%eax)
STACK_SWITCH
-
- movl %edi, PT_UC(%eax)
pushl %esi /* ucontext_t *ucp */
call *PIC_GOTOFF(_C_LABEL(_md_setcontext_u))
@@ -228,10 +231,10 @@ ENTRY(pthread__locked_switch)
leal locked_return_point, %esi
#endif
movl %esi, UC_EIP(%edi)
+ movl %edi, PT_UC(%eax)
STACK_SWITCH
- movl %edi, PT_UC(%eax)
/*
* Check if the original thread was preempted while holding
* its queue lock.
@@ -254,13 +257,6 @@ ENTRY(pthread__locked_switch)
movl %edx, PT_HELDLOCK(%eax)
decl PT_SPINLOCKS(%eax)
- /*
- * Save the context we previously stored in PT_UC(%eax);
- * that was overwritten when we were preempted and continued,
- * so we need to put it somewhere.
- */
- movl %edi, PT_SLEEPUC(%eax)
-
movl PT_NEXT(%eax), %edx
movl %ecx, %eax
movl %edx, %ecx
diff --git a/lib/libpthread/arch/m68k/pthread_switch.S b/lib/libpthread/arch/m68k/pthread_switch.S
index 012cca294a7..d4cb581ca4b 100644
--- a/lib/libpthread/arch/m68k/pthread_switch.S
+++ b/lib/libpthread/arch/m68k/pthread_switch.S
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_switch.S,v 1.3 2003/06/13 07:45:17 scw Exp $ */
+/* $NetBSD: pthread_switch.S,v 1.4 2003/06/26 01:45:32 nathanw Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -103,9 +103,12 @@
*/
#define STACK_SWITCH(pt,tmp) \
- movl %pt@(PT_UC),%tmp ; \
- lea %tmp@(-STACKSPACE),%sp
-
+ movl %pt@(PT_TRAPUC),%tmp ; \
+ bne 1f ; \
+ movl %pt@(PT_UC),%tmp ; \
+1: lea %tmp@(-STACKSPACE),%sp ; \
+ clr %pt@(PT_TRAPUC)
+
/*
* void pthread__switch(pthread_t self, pthread_t next);
*
@@ -135,10 +138,10 @@ ENTRY(pthread__switch)
movl %sp@(RND_CTXSIZE+4),%a0 /* `self': Thread to switch from */
movl %sp@(RND_CTXSIZE+8),%a1 /* `next': Thread to switch to */
movl %sp,%a2 /* a3 = &context */
+ movl %a2,%a0@(PT_UC) /* self->pt_uc = &context */
STACK_SWITCH(a1,a3) /* side effect: a3 = next->pt_uc */
- movl %a2,%a0@(PT_UC) /* self->pt_uc = &context */
/*
* Restore `next's context
@@ -242,12 +245,6 @@ ENTRY(pthread__locked_switch)
movl %a1,%a2@(PT_SWITCHTO)
subql #1,%a2@(PT_SPINLOCKS)
- /* Save the context we previously stored in self->pt_uc
- * that was overwritten when we were preempted and continued,
- * so we need to put it somewhere.
- */
- movl %a4,%a2@(PT_SLEEPUC)
-
/* a1 already == from */
movl %d0,%a2 /* to = self->pt_next */
jbra Lpthread__switch_away_decrement
diff --git a/lib/libpthread/arch/mips/pthread_switch.S b/lib/libpthread/arch/mips/pthread_switch.S
index 3986ab93bc6..7ee385e6add 100644
--- a/lib/libpthread/arch/mips/pthread_switch.S
+++ b/lib/libpthread/arch/mips/pthread_switch.S
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_switch.S,v 1.4 2003/06/12 23:19:27 nathanw Exp $ */
+/* $NetBSD: pthread_switch.S,v 1.5 2003/06/26 01:45:32 nathanw Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -80,9 +80,11 @@
*/
#define STACK_SWITCH(pt,tmp) \
+ lw tmp, PT_TRAPUC(pt) ; \
+ bnez tmp, 1f ; \
lw tmp, PT_UC(pt) ; \
- la sp, -STACKSPACE(tmp)
-
+1: la sp, -STACKSPACE(tmp) ; \
+ sw zero, PT_TRAPUC(pt)
NESTED(pthread__switch, CALLFRAME_SIZ+CONTEXTSIZE, ra)
.mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
@@ -101,10 +103,9 @@ NESTED(pthread__switch, CALLFRAME_SIZ+CONTEXTSIZE, ra)
la t3, CALLFRAME_SIZ(sp)
la t1, pthread__switch_return_point
sw t1, UC_EPC(t3)
+ sw t3, PT_UC(a0)
STACK_SWITCH(a1, t2)
-
- sw t3, PT_UC(a0)
move a0, t2
PIC_CALL(_setcontext_u, t9)
@@ -165,11 +166,10 @@ NESTED(pthread__locked_switch, CALLFRAME_SIZ+CONTEXTSIZE, ra)
la t3, CALLFRAME_SIZ(sp)
la t1, locked_return_point
sw t1, UC_EPC(t3)
+ sw t3, PT_UC(a0)
STACK_SWITCH(a1, t2)
- sw t3, PT_UC(a0)
-
/* Check if the switcher was preempted and continued to here. */
lw t0, PT_NEXT(a0)
beqz t0, 1f
@@ -191,12 +191,6 @@ NESTED(pthread__locked_switch, CALLFRAME_SIZ+CONTEXTSIZE, ra)
subu t4, t4, 1
sw t4, PT_SPINLOCKS(a0)
- /* Save the context we previously stored in PT_UC(a0);
- * that was overwritten when we were preempted and continued,
- * so we need to put it somewhere.
- */
- sw t3, PT_SLEEPUC(a0)
-
move a0, a1
move a1, t0
li a2, 1
diff --git a/lib/libpthread/arch/powerpc/pthread_switch.S b/lib/libpthread/arch/powerpc/pthread_switch.S
index 91802736310..addbe32414f 100644
--- a/lib/libpthread/arch/powerpc/pthread_switch.S
+++ b/lib/libpthread/arch/powerpc/pthread_switch.S
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_switch.S,v 1.6 2003/06/24 18:54:56 nathanw Exp $ */
+/* $NetBSD: pthread_switch.S,v 1.7 2003/06/26 01:45:32 nathanw Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -58,10 +58,14 @@
* Evil STACK_SWITCH()
* See comments in ../i386/pthread_switch.S.
*/
-#define STACK_SWITCH(pt,tmp) \
+#define STACK_SWITCH(pt,tmp,z) \
+ lwz tmp, PT_TRAPUC(pt) ; \
+ or. tmp, tmp, tmp ; \
+ bne 1f ; \
lwz tmp, PT_UC(pt) ; \
- la %r1, -STACKSPACE(tmp)
-
+1: la %r1, -STACKSPACE(tmp) ; \
+ li z, 0 ; \
+ stw z, PT_TRAPUC(pt)
/*
* void
@@ -115,11 +119,10 @@ ENTRY(pthread__switch)
addi %r6, %r6, pthread__switch_return_point@l
#endif
stw %r6, (_REG_PC + 16)(%r1)
-
- STACK_SWITCH(%r4, %r7)
-
stw %r31, PT_UC(%r3)
+ STACK_SWITCH(%r4, %r7, %r6)
+
2: mr %r3, %r7
b PIC_PLT(_C_LABEL(_setcontext_u))
NOTREACHED
@@ -134,7 +137,7 @@ ENTRY_NOPROFILE(pthread__switch_return_point)
pthread__switch_away:
- STACK_SWITCH(%r4,%r6)
+ STACK_SWITCH(%r4, %r6, %r7)
or. %r5, %r5, %r5
beq 1f
@@ -155,7 +158,7 @@ ENTRY(pthread__upcall_switch)
addi %r6, %r6, 1
stw %r6, PT_SPINLOCKS(%r4)
- STACK_SWITCH(%r4,%r5)
+ STACK_SWITCH(%r4, %r5, %r6)
lwz %r7, PT_NEXT(%r3)
or. %r7, %r7, %r7
@@ -270,11 +273,10 @@ ENTRY(pthread__locked_switch)
addi %r6, %r6, locked_return@l
#endif
stw %r6, (_REG_PC + 16)(%r1)
-
- STACK_SWITCH(%r4, %r7)
-
stw %r31, PT_UC(%r3)
+ STACK_SWITCH(%r4, %r7, %r6)
+
/* Check if the switcher was preempted and continued to here. */
lwz %r8, PT_NEXT(%r3)
or. %r8, %r8, %r8
@@ -296,13 +298,6 @@ ENTRY(pthread__locked_switch)
addi %r6, %r6, -1
stw %r6, PT_SPINLOCKS(%r3)
- /*
- * Save the context we previously stored in PT_UC(%r3);
- * that was overwritten when we were preempted and continued,
- * so we need to put it somewhere.
- */
- stw %r31, PT_SLEEPUC(%r3)
-
mr %r3, %r4
mr %r4, %r8
li %r5, 1
diff --git a/lib/libpthread/arch/sparc/pthread_switch.S b/lib/libpthread/arch/sparc/pthread_switch.S
index 637df813a54..501d84dad0c 100644
--- a/lib/libpthread/arch/sparc/pthread_switch.S
+++ b/lib/libpthread/arch/sparc/pthread_switch.S
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_switch.S,v 1.3 2003/06/17 23:18:48 martin Exp $ */
+/* $NetBSD: pthread_switch.S,v 1.4 2003/06/26 01:45:32 nathanw Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -64,9 +64,14 @@
* tmp - temporary register which will have *ucontext_t for that pthread
*/
#define STACK_SWITCH(pt, tmp) \
+ ld [pt + PT_TRAPUC], tmp ; \
+ tst tmp ; \
+ bnz 1f ; \
+ nop ; \
ld [pt + PT_UC], tmp ; \
- add tmp, -STACK_ALIGN(STACKSPACE + CONTEXTSIZE), %sp
-
+1: add tmp, -STACK_ALIGN(STACKSPACE + CONTEXTSIZE), %sp ; \
+ st %g0, [pt + PT_TRAPUC]
+
/*
* void pthread__switch(pthread_t self, pthread_t next);
*
@@ -90,11 +95,10 @@ ENTRY(pthread__switch)
set pthread__switch_return_point, %l1
#endif
st %l1, [%l3 + UC_GREGS + _REG_PC * 4]
+ st %l3, [%i0 + PT_UC]
STACK_SWITCH(%i1, %l2)
- st %l3, [%i0 + PT_UC]
-
/* %l2 points to next thread's ucontext */
call _C_LABEL(_setcontext_u)
mov %l2, %o0
@@ -235,11 +239,10 @@ ENTRY(pthread__locked_switch)
set locked_return_point, %l1
#endif
st %l1, [%l3 + UC_GREGS + _REG_PC * 4]
+ st %l3, [%i0 + PT_UC]
STACK_SWITCH(%i1, %l2)
- st %l3, [%i0 + PT_UC]
-
/* Check if the switcher was preempted and continued to here. */
ld [%i0 + PT_NEXT], %l4
tst %l4
@@ -262,12 +265,6 @@ ENTRY(pthread__locked_switch)
dec %l0
st %l0, [%i0 + PT_SPINLOCKS]
- /* Save the context we previously stored in [%i0 + PT_UC];
- * that was overwritten when we were preempted and continued,
- * so we need to put it somewhere.
- */
- st %l3, [%i0 + PT_SLEEPUC]
-
mov %i1, %i0
mov %l4, %i1
ba pthread__switch_away
diff --git a/lib/libpthread/arch/sparc64/pthread_switch.S b/lib/libpthread/arch/sparc64/pthread_switch.S
index 77aafc19d42..a584da1a38b 100644
--- a/lib/libpthread/arch/sparc64/pthread_switch.S
+++ b/lib/libpthread/arch/sparc64/pthread_switch.S
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_switch.S,v 1.3 2003/06/15 17:11:36 martin Exp $ */
+/* $NetBSD: pthread_switch.S,v 1.4 2003/06/26 01:45:33 nathanw Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -63,9 +63,12 @@
* tmp temporary register which will have *ucontext_t for that pthread
*/
#define STACK_SWITCH(pt,tmp) \
- ldx [pt + PT_UC], tmp ; \
- add tmp, - STACK_ALIGN(STACKSPACE + CONTEXTSIZE) - BIAS, %sp
-
+ ldx [pt + PT_TRAPUC], tmp ; \
+ brnz,a tmp, 1f ; \
+ nop ; \
+ ldx [pt + PT_UC], tmp ; \
+1: add tmp, - STACK_ALIGN(STACKSPACE + CONTEXTSIZE) - BIAS, %sp ; \
+ stx %g0, [pt + PT_TRAPUC]
ENTRY(pthread__switch)
save %sp, -STACK_ALIGN(CC64FSZ + CONTEXTSIZE), %sp
@@ -82,11 +85,10 @@ ENTRY(pthread__switch)
set pthread__switch_return_point, %l1
#endif
stx %l1, [%l3 + UC_GREGS + _REG_PC * 8]
+ stx %l3, [%i0 + PT_UC]
STACK_SWITCH(%i1, %l2)
- stx %l3, [%i0 + PT_UC]
-
/* %l2 points to next thread's ucontext */
call _C_LABEL(_setcontext_u)
mov %l2, %o0
@@ -224,11 +226,10 @@ ENTRY(pthread__locked_switch)
set locked_return_point, %l1
#endif
stx %l1, [%l3 + UC_GREGS + _REG_PC * 8]
+ stx %l3, [%i0 + PT_UC]
STACK_SWITCH(%i1, %l2)
- stx %l3, [%i0 + PT_UC]
-
/* Check if the switcher was preempted and continued to here. */
ldx [%i0 + PT_NEXT], %l4
brz,a %l4, 1f
@@ -250,12 +251,6 @@ ENTRY(pthread__locked_switch)
dec %l0
st %l0, [%i0 + PT_SPINLOCKS]
- /* Save the context we previously stored in [%i0 + PT_UC];
- * that was overwritten when we were preempted and continued,
- * so we need to put it somewhere.
- */
- stx %l3, [%i0 + PT_SLEEPUC]
-
mov %i1, %i0
mov %l4, %i1
ba pthread__switch_away
diff --git a/lib/libpthread/arch/x86_64/pthread_switch.S b/lib/libpthread/arch/x86_64/pthread_switch.S
index ae26f5ba5b4..5c88f36d21c 100644
--- a/lib/libpthread/arch/x86_64/pthread_switch.S
+++ b/lib/libpthread/arch/x86_64/pthread_switch.S
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_switch.S,v 1.3 2003/06/12 22:03:18 fvdl Exp $ */
+/* $NetBSD: pthread_switch.S,v 1.4 2003/06/26 01:45:33 nathanw Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -102,8 +102,12 @@
*/
#define STACK_SWITCH \
+ movq PT_TRAPUC(%r13), %r11 ; \
+ cmpq $0, %r11 ; \
+ jne 1f ; \
movq PT_UC(%r13), %r11 ; \
- leaq (-STACKSPACE)(%r11), %rsp
+1: leaq (-STACKSPACE)(%r11), %rsp ; \
+ movq $0, PT_TRAPUC(%r13)
/*
@@ -141,10 +145,9 @@ ENTRY(pthread__switch)
leaq pthread__switch_return_point, %r11
#endif
movq %r11, UC_RIP(%r14)
+ movq %r14, PT_UC(%r12)
STACK_SWITCH
-
- movq %r14, PT_UC(%r12)
movq %r11, %rdi /* ucontext_t *ucp */
call PIC_PLT(_C_LABEL(_setcontext_u))
@@ -216,10 +219,10 @@ ENTRY(pthread__locked_switch)
leaq locked_return_point, %r11
#endif
movq %r11, UC_RIP(%r15)
+ movq %r15, PT_UC(%r12)
STACK_SWITCH
- movq %r15, PT_UC(%r12)
/*
* Check if the original thread was preempted while holding
* its queue lock.
@@ -242,13 +245,6 @@ ENTRY(pthread__locked_switch)
movq %r14, PT_HELDLOCK(%r12)
decl PT_SPINLOCKS(%r12)
- /*
- * Save the context we previously stored in PT_UC(%eax);
- * that was overwritten when we were preempted and continued,
- * so we need to put it somewhere.
- */
- movq %r15, PT_SLEEPUC(%r12)
-
movq PT_NEXT(%r12), %r11
movq %r13, %r12
movq %r11, %r13