aboutsummaryrefslogtreecommitdiff
path: root/nptl/sysdeps/unix/sysv/linux/x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/x86_64')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S75
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S66
2 files changed, 117 insertions, 24 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
index 29bc1bcf46..7626d7b250 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
@@ -38,7 +38,14 @@
.globl sem_timedwait
.type sem_timedwait,@function
.align 16
+ cfi_startproc
sem_timedwait:
+ /* First check for cancellation. */
+ movl %fs:CANCELHANDLING, %eax
+ andl $0xfffffff9, %eax
+ cmpl $8, %eax
+ je 11f
+
movl (%rdi), %eax
2: testl %eax, %eax
je 1f
@@ -53,18 +60,29 @@ sem_timedwait:
/* Check whether the timeout value is valid. */
1: pushq %r12
+ cfi_adjust_cfa_offset(8)
pushq %r13
- subq $16, %rsp
+ cfi_adjust_cfa_offset(8)
+ pushq %r14
+ cfi_adjust_cfa_offset(8)
+ subq $24, %rsp
+ cfi_adjust_cfa_offset(24)
movq %rdi, %r12
+ cfi_offset(12, -16) /* %r12 */
movq %rsi, %r13
+ cfi_offset(13, -24) /* %r13 */
/* Check for invalid nanosecond field. */
cmpq $1000000000, 8(%r13)
- movl $EINVAL, %eax
+ movl $EINVAL, %r14d
+ cfi_offset(14, -24) /* %r14 */
jae 6f
-7: xorq %rsi, %rsi
+7: call __pthread_enable_asynccancel
+ movl %eax, 16(%rsp)
+
+ xorq %rsi, %rsi
movq %rsp, %rdi
movq $VSYSCALL_ADDR_vgettimeofday, %rax
callq *%rax
@@ -74,14 +92,14 @@ sem_timedwait:
movq $1000, %rdi
mul %rdi /* Milli seconds to nano seconds. */
movq (%r13), %rdi
- movq 8(%r13), %rdi
+ movq 8(%r13), %rsi
subq (%rsp), %rdi
- subq %rax, %rdi
+ subq %rax, %rsi
jns 5f
addq $1000000000, %rsi
decq %rdi
5: testq %rdi, %rdi
- movl $ETIMEDOUT, %eax
+ movl $ETIMEDOUT, %r14d
js 6f /* Time is already up. */
movq %rdi, (%rsp) /* Store relative timeout. */
@@ -93,38 +111,65 @@ sem_timedwait:
movq $SYS_futex, %rax
xorl %edx, %edx
syscall
+ movq %rax, %r14
- testq %rax, %rax
+ movl 16(%rsp), %edi
+ call __pthread_disable_asynccancel
+
+ testq %r14, %r14
je 9f
- cmpq $-EWOULDBLOCK, %rax
+ cmpq $-EWOULDBLOCK, %r14
jne 3f
-9: movl (%rdi), %eax
+9: movl (%r12), %eax
8: testl %eax, %eax
je 7b
leaq -1(%rax), %rcx
LOCK
- cmpxchgl %ecx, (%rdi)
+ cmpxchgl %ecx, (%r12)
jne 8b
xorl %eax, %eax
-10: addq $16, %rsp
+10: addq $24, %rsp
+ cfi_adjust_cfa_offset(-24)
+ popq %r14
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(14)
popq %r13
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(13)
popq %r12
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(12)
retq
-3: negq %rax
+ cfi_adjust_cfa_offset(48)
+ cfi_offset(12, -16) /* %r12 */
+ cfi_offset(13, -24) /* %r13 */
+ cfi_offset(14, -32) /* %r14 */
+3: negq %r14
6:
#if USE___THREAD
movq errno@gottpoff(%rip), %rdx
- movl %eax, %fs:(%rdx)
+ movl %r14d, %fs:(%rdx)
#else
- movl %eax, %edx
callq __errno_location@plt
- movl %edx, (%rax)
+ movl %r14d, (%rax)
#endif
orl $-1, %eax
jmp 10b
+ cfi_adjust_cfa_offset(-48)
+ cfi_restore(14)
+ cfi_restore(13)
+ cfi_restore(12)
+
+11: /* Canceled. */
+ movq $0xffffffffffffffff, %fs:RESULT
+ LOCK
+ orl $0x10, %fs:CANCELHANDLING
+ movq %fs:CLEANUP_JMP_BUF, %rdi
+ jmp __pthread_unwind
+ cfi_endproc
.size sem_timedwait,.-sem_timedwait
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
index 877ee4c4dc..32742309fb 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
@@ -35,38 +35,86 @@
.globl sem_wait
.type sem_wait,@function
.align 16
+ cfi_startproc
sem_wait:
-3: movl (%rdi), %eax
+ /* First check for cancellation. */
+ movl %fs:CANCELHANDLING, %eax
+ andl $0xfffffff9, %eax
+ cmpl $8, %eax
+ je 4f
+
+ pushq %r12
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(12, -16)
+ pushq %r13
+ cfi_adjust_cfa_offset(8)
+ movq %rdi, %r13
+ cfi_offset(13, -24)
+
+3: movl (%r13), %eax
2: testl %eax, %eax
je 1f
leaq -1(%rax), %rdx
LOCK
- cmpxchgl %edx, (%rdi)
+ cmpxchgl %edx, (%r13)
jne 2b
xorl %eax, %eax
+ popq %r13
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(13)
+ popq %r12
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(12)
+
retq
-1: xorq %r10, %r10
+ cfi_adjust_cfa_offset(16)
+ cfi_offset(12, -16)
+ cfi_offset(13, -24)
+1: call __pthread_enable_asynccancel
+ movl %eax, %r8d
+
+ xorq %r10, %r10
movq $SYS_futex, %rax
+ movq %r13, %rdi
movq %r10, %rsi
movq %r10, %rdx
syscall
+ movq %rax, %r12
+
+ movl %r8d, %edi
+ call __pthread_disable_asynccancel
- testq %rax, %rax
+ testq %r12, %r12
je 3b
- cmpq $-EWOULDBLOCK, %rax
+ cmpq $-EWOULDBLOCK, %r12
je 3b
- negq %rax
+ negq %r12
#if USE___THREAD
movq errno@gottpoff(%rip), %rdx
- movl %eax, %fs:(%rdx)
+ movl %r12d, %fs:(%rdx)
#else
- movl %eax, %edx
callq __errno_location@plt
- movl %edx, (%rax)
+ movl %r12d, (%rax)
#endif
orl $-1, %eax
+
+ popq %r13
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(13)
+ popq %r12
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(12)
+
retq
+
+4: /* Canceled. */
+ movq $0xffffffffffffffff, %fs:RESULT
+ LOCK
+ orl $0x10, %fs:CANCELHANDLING
+ movq %fs:CLEANUP_JMP_BUF, %rdi
+ jmp __pthread_unwind
+ cfi_endproc
.size sem_wait,.-sem_wait