From eb7721f232df0721906eeb0993651aa8c32aed8d Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 23 Jul 2007 16:07:53 +0000 Subject: * pthread_rwlock_rdlock.c (__pthread_rwlock_rdlock): Add LLL_SHARED parameter to lll_futex_wait call. * pthread_rwlock_wrlock.c (__pthread_rwlock_wrlock): Likewise. * sysdeps/unix/sysv/linux/powerpc/pthread_once.c (__pthread_once): Replace lll_futex_wait with lll_private_futex_wait. * sysdeps/unix/sysv/linux/powerpc/sem_post.c (__new_sem_post): Add LLL_SHARED parameter to lll_futex_wake(). * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Define LLL_PRIVATE LLL_SHARED, lll_private_futex_wait, lll_private_futex_timed_wait and lll_private_futex_wake. (lll_futex_wait): Add private parameter. Adjust FUTEX_PRIVATE_FLAG bit from private parm before syscall. (lll_futex_timed_wait): Likewise. (lll_futex_wake): Likewise. (lll_futex_wake_unlock): Likewise. (lll_mutex_unlock): Add LLL_SHARED parm to lll_futex_wake call. (lll_robust_mutex_unlock): Likewise. (lll_mutex_unlock_force): Likewise. (lll_wait_tid): Add LLL_SHARED parm to lll_futex_wait call. --- nptl/ChangeLog | 24 ++++++ nptl/pthread_rwlock_rdlock.c | 4 +- nptl/pthread_rwlock_wrlock.c | 6 +- .../sysdeps/unix/sysv/linux/powerpc/lowlevellock.h | 87 ++++++++++++++++++---- .../sysdeps/unix/sysv/linux/powerpc/pthread_once.c | 8 +- nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c | 4 +- 6 files changed, 111 insertions(+), 22 deletions(-) (limited to 'nptl') diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 24c29e6e2a..98882b3e65 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,27 @@ +2007-07-10 Steven Munroe + + * pthread_rwlock_rdlock.c (__pthread_rwlock_rdlock): Add LLL_SHARED + parameter to lll_futex_wait call. + * pthread_rwlock_wrlock.c (__pthread_rwlock_wrlock): Likewise. + + * sysdeps/unix/sysv/linux/powerpc/pthread_once.c (__pthread_once): + Replace lll_futex_wait with lll_private_futex_wait. + * sysdeps/unix/sysv/linux/powerpc/sem_post.c (__new_sem_post): + Add LLL_SHARED parameter to lll_futex_wake(). + + * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Define LLL_PRIVATE + LLL_SHARED, lll_private_futex_wait, lll_private_futex_timed_wait and + lll_private_futex_wake. + (lll_futex_wait): Add private parameter. Adjust FUTEX_PRIVATE_FLAG + bit from private parm before syscall. + (lll_futex_timed_wait): Likewise. + (lll_futex_wake): Likewise. + (lll_futex_wake_unlock): Likewise. + (lll_mutex_unlock): Add LLL_SHARED parm to lll_futex_wake call. + (lll_robust_mutex_unlock): Likewise. + (lll_mutex_unlock_force): Likewise. + (lll_wait_tid): Add LLL_SHARED parm to lll_futex_wait call. + 2007-07-23 Ulrich Drepper * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S: Fix diff --git a/nptl/pthread_rwlock_rdlock.c b/nptl/pthread_rwlock_rdlock.c index 6764c1e9ad..b8f9d41d6a 100644 --- a/nptl/pthread_rwlock_rdlock.c +++ b/nptl/pthread_rwlock_rdlock.c @@ -77,7 +77,9 @@ __pthread_rwlock_rdlock (rwlock) lll_mutex_unlock (rwlock->__data.__lock); /* Wait for the writer to finish. */ - lll_futex_wait (&rwlock->__data.__readers_wakeup, waitval); + lll_futex_wait (&rwlock->__data.__readers_wakeup, waitval, + // XYZ check mutex flag + LLL_SHARED); /* Get the lock. */ lll_mutex_lock (rwlock->__data.__lock); diff --git a/nptl/pthread_rwlock_wrlock.c b/nptl/pthread_rwlock_wrlock.c index 822aeed79c..134b3e95d0 100644 --- a/nptl/pthread_rwlock_wrlock.c +++ b/nptl/pthread_rwlock_wrlock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky , 2003. @@ -68,7 +68,9 @@ __pthread_rwlock_wrlock (rwlock) lll_mutex_unlock (rwlock->__data.__lock); /* Wait for the writer or reader(s) to finish. */ - lll_futex_wait (&rwlock->__data.__writer_wakeup, waitval); + lll_futex_wait (&rwlock->__data.__writer_wakeup, waitval, + // XYZ check mutex flag + LLL_SHARED); /* Get the lock. */ lll_mutex_lock (rwlock->__data.__lock); diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h index 20547f94f2..081d790244 100644 --- a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h +++ b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h @@ -39,37 +39,46 @@ #define FUTEX_TRYLOCK_PI 8 #define FUTEX_PRIVATE_FLAG 128 +/* Values for 'private' parameter of locking macros. Yes, the + definition seems to be backwards. But it is not. The bit will be + reversed before passing to the system call. */ +#define LLL_PRIVATE 0 +#define LLL_SHARED FUTEX_PRIVATE_FLAG + /* Initializer for compatibility lock. */ #define LLL_MUTEX_LOCK_INITIALIZER (0) -#define lll_futex_wait(futexp, val) \ +#define lll_futex_wait(futexp, val, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ + long int opt_flags = (FUTEX_WAIT | LLL_SHARED) ^ private; \ long int __ret; \ \ __ret = INTERNAL_SYSCALL (futex, __err, 4, \ - (futexp), FUTEX_WAIT, (val), 0); \ + (futexp), opt_flags, (val), 0); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ }) -#define lll_futex_timed_wait(futexp, val, timespec) \ +#define lll_futex_timed_wait(futexp, val, timespec, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ + long int opt_flags = (FUTEX_WAIT | LLL_SHARED) ^ private; \ long int __ret; \ \ __ret = INTERNAL_SYSCALL (futex, __err, 4, \ - (futexp), FUTEX_WAIT, (val), (timespec)); \ + (futexp), opt_flags, (val), (timespec)); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ }) -#define lll_futex_wake(futexp, nr) \ +#define lll_futex_wake(futexp, nr, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ + long int opt_flags = (FUTEX_WAKE | LLL_SHARED) ^ private; \ long int __ret; \ \ __ret = INTERNAL_SYSCALL (futex, __err, 4, \ - (futexp), FUTEX_WAKE, (nr), 0); \ + (futexp), opt_flags, (nr), 0); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ }) @@ -97,17 +106,69 @@ }) /* Returns non-zero if error happened, zero if success. */ -#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) \ +#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ + long int opt_flags = (FUTEX_WAKE_OP | LLL_SHARED) ^ private; \ + long int opt_flag2 = (FUTEX_OP_CLEAR_WAKE_IF_GT_ONE | LLL_SHARED) \ + ^ private; \ long int __ret; \ \ __ret = INTERNAL_SYSCALL (futex, __err, 6, \ - (futexp), FUTEX_WAKE_OP, (nr_wake), \ + (futexp), opt_flags, (nr_wake), \ (nr_wake2), (futexp2), \ - FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \ + opt_flag2); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ }) + + +#define lll_private_futex_wait(futexp, val) \ + lll_private_futex_timed_wait (futexp, val, NULL) + + +#ifdef __ASSUME_PRIVATE_FUTEX +# define lll_private_futex_timed_wait(futexp, val, timeout) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, \ + (futexp), (FUTEX_WAIT | FUTEX_PRIVATE_FLAG), \ + (val), (timeout)); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ + }) + +# define lll_private_futex_wake(futexp, val) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, \ + (futexp), (FUTEX_WAKE | FUTEX_PRIVATE_FLAG), \ + (val), 0); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ + }) +#else +# define lll_private_futex_timed_wait(futexp, val, timeout) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, \ + (futexp), FUTEX_WAIT, (val), (timeout)); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ + }) + +# define lll_private_futex_wake(futexp, val) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, \ + (futexp), FUTEX_WAKE, (val), 0); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ + }) +#endif #ifdef UP # define __lll_acq_instr "" @@ -230,7 +291,7 @@ extern int __lll_robust_timedlock_wait int *__futex = &(lock); \ int __val = atomic_exchange_rel (__futex, 0); \ if (__builtin_expect (__val > 1, 0)) \ - lll_futex_wake (__futex, 1); \ + lll_futex_wake (__futex, 1, LLL_SHARED); \ })) #define lll_robust_mutex_unlock(lock) \ @@ -238,7 +299,7 @@ extern int __lll_robust_timedlock_wait int *__futex = &(lock); \ int __val = atomic_exchange_rel (__futex, 0); \ if (__builtin_expect (__val & FUTEX_WAITERS, 0)) \ - lll_futex_wake (__futex, 1); \ + lll_futex_wake (__futex, 1, LLL_SHARED); \ })) #define lll_mutex_unlock_force(lock) \ @@ -246,7 +307,7 @@ extern int __lll_robust_timedlock_wait int *__futex = &(lock); \ *__futex = 0; \ __asm __volatile (__lll_rel_instr ::: "memory"); \ - lll_futex_wake (__futex, 1); \ + lll_futex_wake (__futex, 1, LLL_SHARED); \ })) #define lll_mutex_islocked(futex) \ @@ -281,7 +342,7 @@ typedef int lll_lock_t; do { \ __typeof (tid) __tid; \ while ((__tid = (tid)) != 0) \ - lll_futex_wait (&(tid), __tid); \ + lll_futex_wait (&(tid), __tid, LLL_SHARED); \ } while (0) extern int __lll_timedwait_tid (int *, const struct timespec *) diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c index e1afff8a38..3224568fb7 100644 --- a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c +++ b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Paul Mackerras , 2003. @@ -30,7 +30,7 @@ clear_once_control (void *arg) pthread_once_t *once_control = (pthread_once_t *) arg; *once_control = 0; - lll_futex_wake (once_control, INT_MAX); + lll_private_futex_wake (once_control, INT_MAX); } @@ -74,7 +74,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void)) break; /* Same generation, some other thread was faster. Wait. */ - lll_futex_wait (once_control, oldval); + lll_private_futex_wait (once_control, oldval); } @@ -92,7 +92,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void)) atomic_increment (once_control); /* Wake up all other threads. */ - lll_futex_wake (once_control, INT_MAX); + lll_private_futex_wake (once_control, INT_MAX); return 0; } diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c b/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c index 91b9955181..0b18cdbcde 100644 --- a/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c +++ b/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c @@ -1,5 +1,5 @@ /* sem_post -- post to a POSIX semaphore. Powerpc version. - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Paul Mackerras , 2003. @@ -33,7 +33,7 @@ __new_sem_post (sem_t *sem) __asm __volatile (__lll_rel_instr ::: "memory"); int nr = atomic_increment_val (futex); - int err = lll_futex_wake (futex, nr); + int err = lll_futex_wake (futex, nr, LLL_SHARED); if (__builtin_expect (err, 0) < 0) { __set_errno (-err); -- cgit 1.4.1