glibc/sysdeps/unix/sysv/linux/x86_64/cancellation.S

114 lines
3.1 KiB
ArmAsm
Raw Normal View History

/* Copyright (C) 2009-2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <sysdep.h>
#include <tcb-offsets.h>
#include <kernel-features.h>
#include "lowlevellock.h"
Remove IS_IN_libpthread Replace with IS_IN (libpthread). Generated code unchanged on x86_64. * nptl/lowlevellock.c: Use IS_IN instead of IS_IN_libpthread. * nptl/pthreadP.h: Likewise. * nptl_db/structs.def: Likewise. * sysdeps/arm/sysdep.h: Likewise. * sysdeps/nptl/bits/libc-lock.h: Likewise. * sysdeps/nptl/bits/libc-lockP.h: Likewise. * sysdeps/sparc/sparc32/lowlevellock.c: Likewise. * sysdeps/unix/alpha/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/aarch64/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/arm/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/i386/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/ia64/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/mips/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/not-cancel.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/tile/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/tile/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/tile/waitpid.S: Likewise. * sysdeps/unix/sysv/linux/x86_64/cancellation.S: Likewise. * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h: Likewise.
2014-11-20 08:52:40 +00:00
#if IS_IN (libpthread)
2013-09-04 15:25:42 +00:00
# if defined SHARED && !defined NO_HIDDEN
# define __pthread_unwind __GI___pthread_unwind
# endif
#else
# ifndef SHARED
.weak __pthread_unwind
# endif
#endif
#ifdef __ASSUME_PRIVATE_FUTEX
# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
movl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
#else
# if FUTEX_WAIT == 0
# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
movl %fs:PRIVATE_FUTEX, reg
# else
# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
movl %fs:PRIVATE_FUTEX, reg ; \
orl $FUTEX_WAIT, reg
# endif
#endif
/* It is crucial that the functions in this file don't modify registers
other than %rax and %r11. The syscall wrapper code depends on this
because it doesn't explicitly save the other registers which hold
relevant values. */
.text
.hidden __pthread_enable_asynccancel
ENTRY(__pthread_enable_asynccancel)
movl %fs:CANCELHANDLING, %eax
2: movl %eax, %r11d
orl $TCB_CANCELTYPE_BITMASK, %r11d
cmpl %eax, %r11d
je 1f
lock
cmpxchgl %r11d, %fs:CANCELHANDLING
jnz 2b
andl $(TCB_CANCELSTATE_BITMASK|TCB_CANCELTYPE_BITMASK|TCB_CANCELED_BITMASK|TCB_EXITING_BITMASK|TCB_CANCEL_RESTMASK|TCB_TERMINATED_BITMASK), %r11d
cmpl $(TCB_CANCELTYPE_BITMASK|TCB_CANCELED_BITMASK), %r11d
je 3f
1: ret
2011-08-09 14:07:10 +00:00
3: subq $8, %rsp
cfi_adjust_cfa_offset(8)
2012-05-15 17:19:11 +00:00
LP_OP(mov) $TCB_PTHREAD_CANCELED, %fs:RESULT
lock
orl $TCB_EXITING_BITMASK, %fs:CANCELHANDLING
2012-05-15 17:19:11 +00:00
mov %fs:CLEANUP_JMP_BUF, %RDI_LP
call JUMPTARGET(__pthread_unwind)
hlt
END(__pthread_enable_asynccancel)
.hidden __pthread_disable_asynccancel
ENTRY(__pthread_disable_asynccancel)
testl $TCB_CANCELTYPE_BITMASK, %edi
jnz 1f
movl %fs:CANCELHANDLING, %eax
2: movl %eax, %r11d
andl $~TCB_CANCELTYPE_BITMASK, %r11d
lock
cmpxchgl %r11d, %fs:CANCELHANDLING
jnz 2b
movl %r11d, %eax
3: andl $(TCB_CANCELING_BITMASK|TCB_CANCELED_BITMASK), %eax
cmpl $TCB_CANCELING_BITMASK, %eax
je 4f
1: ret
/* Performance doesn't matter in this loop. We will
delay until the thread is canceled. And we will unlikely
enter the loop twice. */
2012-05-15 17:19:11 +00:00
4: mov %fs:0, %RDI_LP
movl $__NR_futex, %eax
xorq %r10, %r10
addq $CANCELHANDLING, %rdi
LOAD_PRIVATE_FUTEX_WAIT (%esi)
syscall
movl %fs:CANCELHANDLING, %eax
jmp 3b
END(__pthread_disable_asynccancel)