summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Foxley <austinf@cetoncorp.com>2009-12-11 03:46:37 -0800
committerAustin Foxley <austinf@cetoncorp.com>2009-12-11 03:46:37 -0800
commit1c4f98663635995919a2fe7f9c4cbf630ae238d2 (patch)
treeb58c370583a937739249ca21a0fe64e5be8761db
parent5ea195692d4e18c3fe317bcc4428777d8adab3a3 (diff)
get x86_64 nptl building
Signed-off-by: Austin Foxley <austinf@cetoncorp.com>
-rw-r--r--libc/misc/sysvipc/msgq.c2
-rw-r--r--libc/sysdeps/linux/x86_64/Makefile.arch12
-rw-r--r--libc/sysdeps/linux/x86_64/bits/uClibc_arch_features.h2
-rw-r--r--libc/sysdeps/linux/x86_64/vfork.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in3
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c6
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile17
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile.arch73
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h30
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S116
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S11
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S22
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S22
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h35
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S306
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pt-vfork.S4
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S4
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S5
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c14
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_spin_init.c2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S3
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S3
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h63
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep.h259
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_create.c28
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_delete.c27
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_getoverr.c27
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_gettime.c27
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_settime.c27
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/vfork.S16
-rw-r--r--libpthread/nptl/sysdeps/x86_64/Makefile9
-rw-r--r--libpthread/nptl/sysdeps/x86_64/Makefile.arch52
-rw-r--r--libpthread/nptl/sysdeps/x86_64/pthreaddef.h17
-rw-r--r--libpthread/nptl/sysdeps/x86_64/sysdep.h114
-rw-r--r--libpthread/nptl/sysdeps/x86_64/tls.h165
48 files changed, 1245 insertions, 318 deletions
diff --git a/libc/misc/sysvipc/msgq.c b/libc/misc/sysvipc/msgq.c
index e20e3ca64..27eb1ff92 100644
--- a/libc/misc/sysvipc/msgq.c
+++ b/libc/misc/sysvipc/msgq.c
@@ -65,7 +65,7 @@ static inline ssize_t do_msgrcv (int msqid, void *msgp, size_t msgsz,
return __syscall_ipc(IPCOP_msgrcv ,msqid ,msgsz ,msgflg ,&temp, 0);
#endif
}
-int msgrcv (int msqid, void *msgp, size_t msgsz,
+ssize_t msgrcv (int msqid, void *msgp, size_t msgsz,
long int msgtyp, int msgflg)
{
if (SINGLE_THREAD_P)
diff --git a/libc/sysdeps/linux/x86_64/Makefile.arch b/libc/sysdeps/linux/x86_64/Makefile.arch
index 044f97f95..de7ce7285 100644
--- a/libc/sysdeps/linux/x86_64/Makefile.arch
+++ b/libc/sysdeps/linux/x86_64/Makefile.arch
@@ -5,7 +5,15 @@
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := brk.c sigaction.c __syscall_error.c mmap.c
+CSRC := brk.c __syscall_error.c mmap.c
+
+ifneq ($(UCLIBC_HAS_THREADS_NATIVE),y)
+CSRC += sigaction.c
+endif
SSRC := \
- __longjmp.S vfork.S setjmp.S syscall.S bsd-setjmp.S bsd-_setjmp.S clone.S
+ __longjmp.S setjmp.S syscall.S bsd-setjmp.S bsd-_setjmp.S
+
+ifneq ($(UCLIBC_HAS_THREADS_NATIVE),y)
+SSRC += vfork.S clone.S
+endif
diff --git a/libc/sysdeps/linux/x86_64/bits/uClibc_arch_features.h b/libc/sysdeps/linux/x86_64/bits/uClibc_arch_features.h
index 748e544bb..1d966aee4 100644
--- a/libc/sysdeps/linux/x86_64/bits/uClibc_arch_features.h
+++ b/libc/sysdeps/linux/x86_64/bits/uClibc_arch_features.h
@@ -36,7 +36,7 @@
#undef __UCLIBC_HAVE_ASM_GLOBAL_DOT_NAME__
/* define if target supports CFI pseudo ops */
-#undef __UCLIBC_HAVE_ASM_CFI_DIRECTIVES__
+#define __UCLIBC_HAVE_ASM_CFI_DIRECTIVES__
/* define if target supports IEEE signed zero floats */
#define __UCLIBC_HAVE_SIGNED_ZERO__
diff --git a/libc/sysdeps/linux/x86_64/vfork.S b/libc/sysdeps/linux/x86_64/vfork.S
index 2dadbbfe0..97c9c5b67 100644
--- a/libc/sysdeps/linux/x86_64/vfork.S
+++ b/libc/sysdeps/linux/x86_64/vfork.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2002, 2004, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -31,7 +31,7 @@
.text
.global __vfork
.hidden __vfork
-.type __vfork,%function
+.type __vfork,%function
__vfork:
@@ -39,6 +39,10 @@ __vfork:
is preserved by the syscall and that we're allowed to destroy. */
popq %rdi
+#ifdef SAVE_PID
+ SAVE_PID
+#endif
+
/* Stuff the syscall number in RAX and enter into the kernel. */
movl $__NR_vfork, %eax
syscall
@@ -46,6 +50,10 @@ __vfork:
/* Push back the return PC. */
pushq %rdi
+#ifdef RESTORE_PID
+ RESTORE_PID
+#endif
+
cmpl $-4095, %eax
jae __syscall_error /* Branch forward if it failed. */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in b/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in
index 01b2cdd8a..fce368f5a 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in
@@ -63,8 +63,9 @@ X86_PTHREAD_SPECIFIC := sem_post.c sem_wait.c sem_timedwait.c sem_trywait.c
libpthread_CSRC := $(filter-out $(X86_PTHREAD_SPECIFIC),$(libpthread_CSRC))
endif
-
ifeq ($(TARGET_ARCH),x86_64)
+X86_PTHREAD_SPECIFIC := sem_post.c sem_wait.c sem_timedwait.c sem_trywait.c
+libpthread_CSRC := $(filter-out $(X86_PTHREAD_SPECIFIC),$(libpthread_CSRC))
librt_CSRC := mq_notify.c
endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c
index 5f9380814..155d3645f 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c
@@ -33,9 +33,9 @@ int __libc_missing_posix_timers attribute_hidden;
#endif
int
-pthread_getcpuclockid (threadid, clockid)
- pthread_t threadid;
- clockid_t *clockid;
+pthread_getcpuclockid (
+ pthread_t threadid,
+ clockid_t *clockid)
{
struct pthread *pd = (struct pthread *) threadid;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile
index b32ce29ef..43a6fad84 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile
@@ -1,4 +1,13 @@
-ifeq ($(subdir),nptl)
-CFLAGS-pt-initfini.s = -g0 -fPIC -fno-inline-functions \
- -fno-asynchronous-unwind-tables $(fno-unit-at-a-time)
-endif
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2005 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+top_srcdir=../../../../../../../
+top_builddir=../../../../../../../
+all: objs
+include $(top_builddir)Rules.mak
+include Makefile.arch
+include $(top_srcdir)Makerules
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile.arch
new file mode 100644
index 000000000..e50539a36
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile.arch
@@ -0,0 +1,73 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2006 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+LINUX_ARCH_DIR:=$(top_srcdir)libpthread/nptl/sysdeps/unix/sysv/linux/x86_64
+LINUX_ARCH_OUT:=$(top_builddir)libpthread/nptl/sysdeps/unix/sysv/linux/x86_64
+
+
+libpthread_SSRC = pt-vfork.S clone.S pthread_once.S
+libpthread_CSRC = pthread_spin_init.c
+
+libc_a_CSRC = fork.c
+libc_a_SSRC = clone.S vfork.S
+
+libpthread_SSRC += lowlevellock.S pthread_barrier_wait.S pthread_cond_signal.S pthread_cond_broadcast.S \
+ sem_post.S sem_timedwait.S \
+ sem_trywait.S sem_wait.S pthread_rwlock_rdlock.S pthread_rwlock_wrlock.S \
+ pthread_rwlock_timedrdlock.S pthread_rwlock_timedwrlock.S pthread_rwlock_unlock.S \
+ pthread_cond_timedwait.S pthread_cond_wait.S
+
+libc_a_SSRC += libc-lowlevellock.S
+
+
+CFLAGS-OMIT-fork.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+
+ifeq ($(UCLIBC_HAS_STDIO_FUTEXES),y)
+CFLAGS-fork.c = -D__USE_STDIO_FUTEXES__
+endif
+
+ASFLAGS-pt-vfork.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-lowlevellock.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-pthread_once.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD
+
+
+ASFLAGS-clone.S = -D_LIBC_REENTRANT
+ASFLAGS-vfork.S = -D_LIBC_REENTRANT
+ASFLAGS-libc-lowlevellock.S = -D_LIBC_REENTRANT
+
+ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y)
+#Needed to use the correct SYSCALL_ERROR_HANDLER
+ASFLAGS-clone.S += -DUSE___THREAD
+ASFLAGS-vfork.S += -DUSE___THREAD
+endif
+
+CFLAGS += $(SSP_ALL_CFLAGS)
+#CFLAGS:=$(CFLAGS:-O1=-O2)
+
+LINUX_ARCH_OBJ:=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libpthread_SSRC))
+LINUX_ARCH_OBJ+=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libpthread_CSRC))
+
+ifeq ($(DOPIC),y)
+libpthread-a-y += $(LINUX_ARCH_OBJ:.o=.os)
+else
+libpthread-a-y += $(LINUX_ARCH_OBJ)
+endif
+libpthread-so-y += $(LINUX_ARCH_OBJ:.o=.oS)
+
+libpthread-nomulti-y+=$(LINUX_ARCH_OBJS)
+
+LIBC_LINUX_ARCH_OBJ:=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libc_a_CSRC))
+LIBC_LINUX_ARCH_OBJ+=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libc_a_SSRC))
+
+libc-static-y+=$(LIBC_LINUX_ARCH_OBJ)
+libc-shared-y+=$(LIBC_LINUX_ARCH_OBJ:.o=.oS)
+
+libc-nomulti-y+=$(LIBC_LINUX_ARCH_OBJ)
+
+objclean-y+=nptl_linux_arch_clean
+
+nptl_linux_arch_clean:
+ $(do_rm) $(addprefix $(LINUX_ARCH_OUT)/*., o os oS)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
index 51fdab0fb..7a09c8119 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -75,7 +75,7 @@ typedef struct __pthread_internal_slist
type is not exposed on purpose. */
typedef union
{
- struct
+ struct __pthread_mutex_s
{
int __lock;
unsigned int __count;
@@ -86,10 +86,18 @@ typedef union
/* KIND must stay at this position in the structure to maintain
binary compatibility. */
int __kind;
-#if __WORDSIZE != 64
+#if __WORDSIZE == 64
+ int __spins;
+ __pthread_list_t __list;
+# define __PTHREAD_MUTEX_HAVE_PREV 1
+#else
unsigned int __nusers;
+ __extension__ union
+ {
+ int __spins;
+ __pthread_slist_t __list;
+ };
#endif
- int __spins;
} __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align;
@@ -151,9 +159,9 @@ typedef union
unsigned int __nr_readers_queued;
unsigned int __nr_writers_queued;
int __writer;
- int __pad1;
+ int __shared;
+ unsigned long int __pad1;
unsigned long int __pad2;
- unsigned long int __pad3;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
unsigned int __flags;
@@ -169,7 +177,10 @@ typedef union
unsigned int __nr_writers_queued;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
- unsigned int __flags;
+ unsigned char __flags;
+ unsigned char __shared;
+ unsigned char __pad1;
+ unsigned char __pad2;
int __writer;
} __data;
# endif
@@ -206,4 +217,9 @@ typedef union
#endif
+#if __WORDSIZE == 32
+/* Extra attributes for the cleanup functions. */
+# define __cleanup_fct_attribute __attribute__ ((__regparm__ (1)))
+#endif
+
#endif /* bits/pthreadtypes.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S
new file mode 100644
index 000000000..680696200
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S
@@ -0,0 +1,116 @@
+/* Copyright (C) 2009 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <tcb-offsets.h>
+#include <kernel-features.h>
+#include "lowlevellock.h"
+
+#ifdef IS_IN_libpthread
+# ifdef SHARED
+# 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
+
+3: movq $TCB_PTHREAD_CANCELED, %fs:RESULT
+ lock
+ orl $TCB_EXITING_BITMASK, %fs:CANCELHANDLING
+ movq %fs:CLEANUP_JMP_BUF, %rdi
+#ifdef SHARED
+ call __pthread_unwind@PLT
+#else
+ call __pthread_unwind
+#endif
+ 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. */
+4: movq %fs:0, %rdi
+ 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)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S
index dfa6adb3e..675a997e9 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S
@@ -1,2 +1,9 @@
-#define RESET_PID
-#include <sysdeps/unix/sysv/linux/x86_64/clone.S>
+/* We want an #include_next, but we are the main source file.
+ So, #include ourselves and in that incarnation we can use #include_next. */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S
new file mode 100644
index 000000000..110058850
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S
@@ -0,0 +1,22 @@
+/* Copyright (C) 2009 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __pthread_enable_asynccancel __libc_enable_asynccancel
+#define __pthread_disable_asynccancel __libc_disable_asynccancel
+#include "cancellation.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
index 3621efa4f..ce8ad27aa 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -17,14 +17,4 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
-/* In libc.so we do not unconditionally use the lock prefix. Only if
- the application is using threads. */
-#ifndef UP
-# define LOCK \
- cmpl $0, __libc_multiple_threads(%rip); \
- je 0f; \
- lock; \
-0:
-#endif
-
#include "lowlevellock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S
new file mode 100644
index 000000000..ce4192b5d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S
@@ -0,0 +1,22 @@
+/* Copyright (C) 2009 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __pthread_enable_asynccancel __librt_enable_asynccancel
+#define __pthread_disable_asynccancel __librt_disable_asynccancel
+#include "cancellation.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
index 3a49e25dd..1e461ad41 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
@@ -30,7 +30,6 @@
# endif
#endif
-#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
index 35cd868d0..c9f30e962 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
@@ -23,6 +23,8 @@
#include <time.h>
#include <sys/param.h>
#include <bits/pthreadtypes.h>
+#include <atomic.h>
+#include <sysdep.h>
#ifndef LOCK_INSTR
# ifdef UP
@@ -32,7 +34,6 @@
# endif
#endif
-#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
@@ -43,14 +44,14 @@
#define LLL_MUTEX_LOCK_INITIALIZER_WAITERS (2)
/* Delay in spinlock loop. */
-#define BUSY_WAIT_NOP asm ("rep; nop")
+#define BUSY_WAIT_NOP __asm__ ("rep; nop")
#define lll_futex_wait(futex, val) \
do { \
int __ignore; \
- register __typeof (val) _val asm ("edx") = (val); \
- __asm __volatile ("xorq %%r10, %%r10\n\t" \
+ register __typeof (val) _val __asm__ ("edx") = (val); \
+ __asm__ __volatile ("xorq %%r10, %%r10\n\t" \
"syscall" \
: "=a" (__ignore) \
: "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAIT), \
@@ -62,8 +63,8 @@
#defin