diff options
-rw-r--r-- | nptl/ChangeLog | 19 | ||||
-rw-r--r-- | nptl/DESIGN-condvar.txt | 3 | ||||
-rw-r--r-- | nptl/init.c | 8 | ||||
-rw-r--r-- | nptl/sysdeps/pthread/pthread_cond_wait.c | 11 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S | 28 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/x86_64/Makefile | 2 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S | 2 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevelmutex.S | 2 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S | 8 | ||||
-rw-r--r-- | nptl/sysdeps/x86_64/tls.h | 3 |
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; \ |