summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/thread/arm/syscall_cp.s6
-rw-r--r--src/thread/i386/syscall_cp.s9
-rw-r--r--src/thread/mips/syscall_cp.s20
-rw-r--r--src/thread/powerpc/syscall_cp.s1
-rw-r--r--src/thread/pthread_cancel.c7
5 files changed, 32 insertions, 11 deletions
diff --git a/src/thread/arm/syscall_cp.s b/src/thread/arm/syscall_cp.s
index 5a2d6c35..66c5ecbd 100644
--- a/src/thread/arm/syscall_cp.s
+++ b/src/thread/arm/syscall_cp.s
@@ -7,7 +7,7 @@ __syscall_cp_asm:
__cp_begin:
ldr r0,[r0]
cmp r0,#0
- blne __cancel
+ blne __cp_cancel
mov r7,r1
mov r0,r2
mov r1,r3
@@ -19,3 +19,7 @@ __cp_end:
tst lr,#1
moveq pc,lr
bx lr
+.global __cp_cancel
+__cp_cancel:
+ ldmfd sp!,{r4,r5,r6,r7,lr}
+ b __cancel
diff --git a/src/thread/i386/syscall_cp.s b/src/thread/i386/syscall_cp.s
index 3bf52c1f..71ce63f7 100644
--- a/src/thread/i386/syscall_cp.s
+++ b/src/thread/i386/syscall_cp.s
@@ -11,7 +11,7 @@ __syscall_cp_asm:
__cp_begin:
movl (%ecx),%eax
testl %eax,%eax
- jnz __cancel
+ jnz __cp_cancel
movl 24(%esp),%eax
movl 28(%esp),%ebx
movl 32(%esp),%ecx
@@ -27,3 +27,10 @@ __cp_end:
popl %esi
popl %ebx
ret
+.global __cp_cancel
+__cp_cancel:
+ popl %ebp
+ popl %edi
+ popl %esi
+ popl %ebx
+ jmp __cancel
diff --git a/src/thread/mips/syscall_cp.s b/src/thread/mips/syscall_cp.s
index b6f30ee8..d903794d 100644
--- a/src/thread/mips/syscall_cp.s
+++ b/src/thread/mips/syscall_cp.s
@@ -3,19 +3,19 @@
.global __syscall_cp_asm
.type __syscall_cp_asm,@function
__syscall_cp_asm:
+ subu $sp, $sp, 32
.global __cp_begin
__cp_begin:
lw $4, 0($4)
- bne $4, $0, 2f
+ bne $4, $0, __cp_cancel
move $2, $5
move $4, $6
move $5, $7
- lw $6, 16($sp)
- lw $7, 20($sp)
- lw $8, 24($sp)
- lw $9, 28($sp)
- lw $10,32($sp)
- subu $sp, $sp, 32
+ lw $6, 48($sp)
+ lw $7, 52($sp)
+ lw $8, 56($sp)
+ lw $9, 60($sp)
+ lw $10,64($sp)
sw $8, 16($sp)
sw $9, 20($sp)
sw $10,24($sp)
@@ -29,6 +29,10 @@ __cp_end:
subu $2, $0, $2
1: jr $ra
nop
-2: lw $25, %call16(__cancel)($gp)
+
+.global __cp_cancel
+__cp_cancel:
+ addu $sp, $sp, 32
+ lw $25, %call16(__cancel)($gp)
jr $25
nop
diff --git a/src/thread/powerpc/syscall_cp.s b/src/thread/powerpc/syscall_cp.s
index 2c97ca04..0c7869cc 100644
--- a/src/thread/powerpc/syscall_cp.s
+++ b/src/thread/powerpc/syscall_cp.s
@@ -31,7 +31,6 @@ __cp_begin:
beq+ cr7, 1f #jump to label 1 if r0 was 0
b __cancel #else call cancel
- # (the return address is not needed, since __cancel never returns)
1:
#ok, the cancel flag was not set
# syscall: number goes to r0, the rest 3-8
diff --git a/src/thread/pthread_cancel.c b/src/thread/pthread_cancel.c
index 4493931e..66e0817c 100644
--- a/src/thread/pthread_cancel.c
+++ b/src/thread/pthread_cancel.c
@@ -1,11 +1,18 @@
#include "pthread_impl.h"
#include "syscall.h"
+#include "libc.h"
void __cancel()
{
pthread_exit(PTHREAD_CANCELED);
}
+/* If __syscall_cp_asm has adjusted the stack pointer, it must provide a
+ * definition of __cp_cancel to undo those adjustments and call __cancel.
+ * Otherwise, __cancel provides a definition for __cp_cancel. */
+
+weak_alias(__cancel, __cp_cancel);
+
long __syscall_cp_asm(volatile void *, syscall_arg_t,
syscall_arg_t, syscall_arg_t, syscall_arg_t,
syscall_arg_t, syscall_arg_t, syscall_arg_t);