summaryrefslogtreecommitdiff
path: root/src/thread
diff options
context:
space:
mode:
Diffstat (limited to 'src/thread')
-rw-r--r--src/thread/arm/syscall_cp.s18
-rw-r--r--src/thread/cancel_impl.c15
-rw-r--r--src/thread/i386/syscall_cp.s36
-rw-r--r--src/thread/x86_64/syscall_cp.s18
4 files changed, 35 insertions, 52 deletions
diff --git a/src/thread/arm/syscall_cp.s b/src/thread/arm/syscall_cp.s
index 59924fc5..0cc23b1f 100644
--- a/src/thread/arm/syscall_cp.s
+++ b/src/thread/arm/syscall_cp.s
@@ -3,20 +3,18 @@
__syscall_cp_asm:
mov ip,sp
stmfd sp!,{r4,r5,r6,r7,lr}
- stmfd sp!,{r0}
- bl 1f
-1: mov r4,#(1f-.)
- add r4,r4,lr
- str r4,[r0,#4]
- str sp,[r0]
+.global __cp_begin
+__cp_begin:
+ ld r0,[r0]
+ cmp r0,#0
+ blne __cancel
mov r7,r1
mov r0,r2
mov r1,r3
ldmfd ip,{r2,r3,r4,r5,r6}
-1: svc 0
- ldmfd sp!,{r1}
- mov r2,#0
- str r2,[r1]
+ svc 0
+.global __cp_end
+__cp_end:
ldmfd sp!,{r4,r5,r6,r7,lr}
tst lr,#1
moveq pc,lr
diff --git a/src/thread/cancel_impl.c b/src/thread/cancel_impl.c
index 7652a7c9..3bf1e392 100644
--- a/src/thread/cancel_impl.c
+++ b/src/thread/cancel_impl.c
@@ -14,19 +14,12 @@ long __syscall_cp_asm(volatile void *, long, long, long, long, long, long, long)
long (__syscall_cp)(long nr, long u, long v, long w, long x, long y, long z)
{
pthread_t self;
- uintptr_t old_sp, old_ip;
long r;
if (!libc.main_thread || (self = __pthread_self())->canceldisable)
return __syscall(nr, u, v, w, x, y, z);
- old_sp = self->cp_sp;
- old_ip = self->cp_ip;
- self->cp_sp = 0;
- self->cp_ip = 0;
- r = __syscall_cp_asm(&self->cp_sp, nr, u, v, w, x, y, z);
- self->cp_ip = old_ip;
- self->cp_sp = old_sp;
+ r = __syscall_cp_asm(&self->cancel, nr, u, v, w, x, y, z);
if (r==-EINTR && nr!=SYS_close && self->cancel && !self->canceldisable)
__cancel();
return r;
@@ -42,14 +35,14 @@ static void cancel_handler(int sig, siginfo_t *si, void *ctx)
{
pthread_t self = __pthread_self();
ucontext_t *uc = ctx;
- uintptr_t sp = ((uintptr_t *)&uc->uc_mcontext)[CANCEL_REG_SP];
- uintptr_t ip = ((uintptr_t *)&uc->uc_mcontext)[CANCEL_REG_IP];
+ const char *ip = ((char **)&uc->uc_mcontext)[CANCEL_REG_IP];
+ extern const char __cp_begin[1], __cp_end[1];
if (!self->cancel || self->canceldisable) return;
_sigaddset(&uc->uc_sigmask, SIGCANCEL);
- if (self->cancelasync || sp == self->cp_sp && ip <= self->cp_ip) {
+ if (self->cancelasync || ip >= __cp_begin && ip < __cp_end) {
self->canceldisable = 1;
pthread_sigmask(SIG_SETMASK, &uc->uc_sigmask, 0);
__cancel();
diff --git a/src/thread/i386/syscall_cp.s b/src/thread/i386/syscall_cp.s
index 05e867a1..3bf52c1f 100644
--- a/src/thread/i386/syscall_cp.s
+++ b/src/thread/i386/syscall_cp.s
@@ -2,34 +2,28 @@
.global __syscall_cp_asm
.type __syscall_cp_asm,@function
__syscall_cp_asm:
+ mov 4(%esp),%ecx
pushl %ebx
pushl %esi
pushl %edi
pushl %ebp
- leal 20(%esp),%ebp
- call 1f
-1: popl %eax
- movl (%ebp),%ecx
- addl $[1f-1b],%eax
- movl %eax,4(%ecx)
- movl %esp,(%ecx)
- movl 8(%ecx),%eax
+.global __cp_begin
+__cp_begin:
+ movl (%ecx),%eax
testl %eax,%eax
- jnz 2f
- movl 4(%ebp),%eax
- movl 8(%ebp),%ebx
- movl 12(%ebp),%ecx
- movl 16(%ebp),%edx
- movl 20(%ebp),%esi
- movl 24(%ebp),%edi
- movl 28(%ebp),%ebp
-1: int $128
+ jnz __cancel
+ movl 24(%esp),%eax
+ movl 28(%esp),%ebx
+ movl 32(%esp),%ecx
+ movl 36(%esp),%edx
+ movl 40(%esp),%esi
+ movl 44(%esp),%edi
+ movl 48(%esp),%ebp
+ int $128
+.global __cp_end
+__cp_end:
popl %ebp
popl %edi
popl %esi
popl %ebx
- xorl %edx,%edx
- movl 4(%esp),%ecx
- movl %edx,(%ecx)
ret
-2: call __cancel
diff --git a/src/thread/x86_64/syscall_cp.s b/src/thread/x86_64/syscall_cp.s
index b0363547..788c53cc 100644
--- a/src/thread/x86_64/syscall_cp.s
+++ b/src/thread/x86_64/syscall_cp.s
@@ -2,12 +2,12 @@
.global __syscall_cp_asm
.type __syscall_cp_asm,@function
__syscall_cp_asm:
- lea 1f(%rip),%rax
- mov %rax,8(%rdi)
- mov %rsp,(%rdi)
- mov 16(%rdi),%eax
+
+.global __cp_begin
+__cp_begin:
+ mov (%rdi),%eax
test %eax,%eax
- jnz 2f
+ jnz __cancel
mov %rdi,%r11
mov %rsi,%rax
mov %rdx,%rdi
@@ -17,9 +17,7 @@ __syscall_cp_asm:
mov 8(%rsp),%r8
mov 16(%rsp),%r9
mov %r11,8(%rsp)
-1: syscall
- xor %ecx,%ecx
- mov 8(%rsp),%rdi
- mov %rcx,(%rdi)
+ syscall
+.global __cp_end
+__cp_end:
ret
-2: call __cancel