diff options
| author | nathanw <nathanw@NetBSD.org> | 2003-06-26 01:45:31 +0000 |
|---|---|---|
| committer | nathanw <nathanw@NetBSD.org> | 2003-06-26 01:45:31 +0000 |
| commit | 9639eeaf5402c011f48282ba82e9d53e0f4a91ef (patch) | |
| tree | 56d434a05cb67889c39c59682ad685cb425153be /lib/libpthread | |
| parent | 487eb7e1931dc8d1b63f2d5260bb26885273333c (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.S | 17 | ||||
| -rw-r--r-- | lib/libpthread/arch/arm/pthread_switch.S | 36 | ||||
| -rw-r--r-- | lib/libpthread/arch/i386/pthread_switch.S | 22 | ||||
| -rw-r--r-- | lib/libpthread/arch/m68k/pthread_switch.S | 19 | ||||
| -rw-r--r-- | lib/libpthread/arch/mips/pthread_switch.S | 20 | ||||
| -rw-r--r-- | lib/libpthread/arch/powerpc/pthread_switch.S | 33 | ||||
| -rw-r--r-- | lib/libpthread/arch/sparc/pthread_switch.S | 23 | ||||
| -rw-r--r-- | lib/libpthread/arch/sparc64/pthread_switch.S | 23 | ||||
| -rw-r--r-- | lib/libpthread/arch/x86_64/pthread_switch.S | 20 |
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 |
