aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nptl/ChangeLog19
-rw-r--r--nptl/DESIGN-condvar.txt3
-rw-r--r--nptl/init.c8
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_wait.c11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S28
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/Makefile2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevelmutex.S2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S8
-rw-r--r--nptl/sysdeps/x86_64/tls.h3
10 files changed, 68 insertions, 18 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index be858950f9..a4cd4f5482 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,22 @@
+2003-03-11 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+ (__condvar_cleanup): Wake up all waiters in case we got signaled
+ after being woken up but before disabling asynchronous
+ cancellation.
+ * sysdeps/pthread/pthread_cond_wait.c (__condvar_cleanup): Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+ (__condvar_cleanup): Likewise.
+
+ * init.c (__NR_set_tid_address): If already defined, don't redefine.
+ Make it an error if architecture has no #if case. Add x86-64.
+
+ * sysdeps/unix/sysv/linux/x86_64/Makefile: Add flags for
+ pt-initfini.s generation.
+
+ * sysdeps/x86_64/tls.h: Include <asm/prctl.h>.
+ (TLS_INIT_TP): Fix typo.
+
2003-03-11 Jakub Jelinek <jakub@redhat.com>
* sysdeps/ia64/bits/atomic.h (atomic_exchange_and_add): Swap 2nd and
diff --git a/nptl/DESIGN-condvar.txt b/nptl/DESIGN-condvar.txt
index 749180ed4b..7202e414ef 100644
--- a/nptl/DESIGN-condvar.txt
+++ b/nptl/DESIGN-condvar.txt
@@ -34,6 +34,9 @@ cleanup_handler(cv)
++cv->wakeup_seq;
++cv->woken_seq;
+ /* make sure no signal gets lost. */
+ FUTEX_WAKE(cv->wakeup_seq, ALL);
+
lll_unlock(cv->lock);
}
diff --git a/nptl/init.c b/nptl/init.c
index e4e30815a6..80bb73d991 100644
--- a/nptl/init.c
+++ b/nptl/init.c
@@ -33,14 +33,20 @@
#include <shlib-compat.h>
+#ifndef __NR_set_tid_address
/* XXX For the time being... Once we can rely on the kernel headers
having the definition remove these lines. */
#if defined __s390__
# define __NR_set_tid_address 252
#elif defined __ia64__
# define __NR_set_tid_address 1233
-#else
+#elif defined __i386__
# define __NR_set_tid_address 258
+#elif defined __x86_64__
+# define __NR_set_tid_address 218
+#eli
+# error "define __NR_set_tid_address"
+#endif
#endif
diff --git a/nptl/sysdeps/pthread/pthread_cond_wait.c b/nptl/sysdeps/pthread/pthread_cond_wait.c
index 399cee89ee..78fcc7f6c6 100644
--- a/nptl/sysdeps/pthread/pthread_cond_wait.c
+++ b/nptl/sysdeps/pthread/pthread_cond_wait.c
@@ -34,6 +34,7 @@ struct _condvar_cleanup_buffer
pthread_mutex_t *mutex;
};
+
void
__attribute__ ((visibility ("hidden")))
__condvar_cleanup (void *arg)
@@ -49,6 +50,16 @@ __condvar_cleanup (void *arg)
++cbuffer->cond->__data.__wakeup_seq;
++cbuffer->cond->__data.__woken_seq;
+ /* Wake everybody to make sure no condvar signal gets lost. */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ int *futex = ((int *) (&cbuffer->cond->__data.__wakeup_seq));
+#elif BYTE_ORDER == BIG_ENDIAN
+ int *futex = ((int *) (&cbuffer->cond->__data.__wakeup_seq)) + 1;
+#else
+# error "No valid byte order"
+#endif
+ lll_futex_wake (futex, INT_MAX);
+
/* We are done. */
lll_mutex_unlock (cbuffer->cond->__data.__lock);
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
index a679ee65e6..b3a49e794a 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
@@ -63,24 +63,24 @@ __condvar_cleanup:
#endif
call __lll_mutex_lock_wait
-1: addl $1, wakeup_seq(%ebx)
- adcl $0, wakeup_seq+4(%ebx)
+1: addl $wakeup_seq, %ebx
+ addl $1, (%ebx)
+ adcl $0, 4(%ebx)
- addl $1, woken_seq(%ebx)
- adcl $0, woken_seq+4(%ebx)
+ addl $1, woken_seq-wakeup_seq(%ebx)
+ adcl $0, woken_seq-wakeup_seq+4(%ebx)
+
+ /* Wake up all waiters to make sure no signal gets lost. */
+ movl $FUTEX_WAKE, %ecx
+ movl $SYS_futex, %eax
+ movl $0x7fffffff, %edx
+ ENTER_KERNEL
LOCK
-#if cond_lock == 0
- subl $1, (%ebx)
-#else
- subl $1, cond_lock(%ebx)
-#endif
+ subl $1, cond_lock-wakeup_seq(%ebx)
je 2f
-#if cond_lock == 0
- movl %ebx, %eax
-#else
- leal cond_lock(%ebx), %eax
-#endif
+
+ leal cond_lock-wakeup_seq(%ebx), %eax
call __lll_mutex_unlock_wake
/* Lock the mutex unless asynchronous cancellation is in effect. */
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile b/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile
index c73c2b6c26..9ecb7b092a 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile
@@ -1,4 +1,6 @@
ifeq ($(subdir),nptl)
+CFLAGS-pt-initfini.s = -g0 -fPIC -fno-inline-functions -fno-asynchronous-unwind-tables
+
# We need to make sure that stack memory is allocated in the low 4GB.
CFLAGS-pthread_create.c += -DARCH_MAP_FLAGS=MAP_32BIT
endif
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
index 2128f1b22e..3621efa4fc 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
@@ -21,7 +21,7 @@
the application is using threads. */
#ifndef UP
# define LOCK \
- cmpl $0, __libc_multiple_threads_ptr(%rip); \
+ cmpl $0, __libc_multiple_threads(%rip); \
je 0f; \
lock; \
0:
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevelmutex.S b/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevelmutex.S
index a4ce9c2fee..e6dc8677a4 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevelmutex.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevelmutex.S
@@ -21,7 +21,7 @@
the application is using threads. */
#ifndef UP
# define LOCK \
- cmpl $0, __libc_multiple_threads_ptr(%rip); \
+ cmpl $0, __libc_multiple_threads(%rip); \
je 0f; \
lock; \
0:
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
index 060f35e8a9..c15566fdf0 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
@@ -65,6 +65,14 @@ __condvar_cleanup:
addq $1, woken_seq(%rdi)
+ /* Wake up all waiters to make sure no signal gets lost. */
+ addq $wakeup_seq, %rdi
+ movq $FUTEX_WAKE, %rsi
+ movl $0x7fffffff, %edx
+ movq $SYS_futex, %rax
+ syscall
+ subq $wakeup_seq, %rdi
+
LOCK
#if cond_lock == 0
decl (%rdi)
diff --git a/nptl/sysdeps/x86_64/tls.h b/nptl/sysdeps/x86_64/tls.h
index ae1c66e373..45646e4485 100644
--- a/nptl/sysdeps/x86_64/tls.h
+++ b/nptl/sysdeps/x86_64/tls.h
@@ -20,6 +20,7 @@
#ifndef _TLS_H
#define _TLS_H 1
+#include <asm/prctl.h> /* For ARCH_SET_FS. */
#ifndef __ASSEMBLER__
# include <stddef.h>
# include <stdint.h>
@@ -123,7 +124,7 @@ typedef struct
: "=a" (_result) \
: "0" ((unsigned long int) __NR_arch_prctl), \
"D" ((unsigned long int) ARCH_SET_FS), \
- "S" (_descr) \
+ "S" (_thrdescr) \
: "memory", "cc", "r11", "cx"); \
\
_result ? "cannot set %fs base address for thread-local storage" : 0; \