From a032a6587011cbdac8c2f7e11f15dc4e592bbb55 Mon Sep 17 00:00:00 2001 From: Austin Foxley Date: Tue, 16 Feb 2010 12:27:18 -0800 Subject: mass sync with glibc nptl Signed-off-by: Austin Foxley --- .../nptl/sysdeps/unix/sysv/linux/powerpc/Versions | 5 - .../unix/sysv/linux/powerpc/bits/pthreadtypes.h | 15 +- .../unix/sysv/linux/powerpc/bits/semaphore.h | 3 - .../sysdeps/unix/sysv/linux/powerpc/lowlevellock.h | 251 +++++++++++++-------- .../unix/sysv/linux/powerpc/powerpc32/clone.S | 12 +- .../sysv/linux/powerpc/powerpc32/sysdep-cancel.h | 37 +-- .../unix/sysv/linux/powerpc/powerpc32/vfork.S | 2 +- .../unix/sysv/linux/powerpc/powerpc64/Versions | 7 - .../unix/sysv/linux/powerpc/powerpc64/clone.S | 12 +- .../sysv/linux/powerpc/powerpc64/sysdep-cancel.h | 16 +- .../unix/sysv/linux/powerpc/powerpc64/vfork.S | 2 +- .../sysdeps/unix/sysv/linux/powerpc/pthread_once.c | 8 +- .../unix/sysv/linux/powerpc/pthread_spin_unlock.c | 29 +++ .../sysdeps/unix/sysv/linux/powerpc/sem_post.c | 19 +- 14 files changed, 259 insertions(+), 159 deletions(-) delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/Versions delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux/powerpc') diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/Versions b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/Versions deleted file mode 100644 index 997784798..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/Versions +++ /dev/null @@ -1,5 +0,0 @@ -libpthread { - GLIBC_2.3.4 { - longjmp; siglongjmp; - } -} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h index c94ed0c38..c0b59c336 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h @@ -1,5 +1,5 @@ /* Machine-specific pthread type layouts. PowerPC version. - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Paul Mackerras , 2003. @@ -57,6 +57,7 @@ typedef union long int __align; } pthread_attr_t; + #if __WORDSIZE == 64 typedef struct __pthread_internal_list { @@ -70,6 +71,7 @@ typedef struct __pthread_internal_slist } __pthread_slist_t; #endif + /* Data structures for mutex handling. The structure of the attribute type is deliberately not exposed. */ typedef union @@ -88,7 +90,7 @@ typedef union #if __WORDSIZE == 64 int __spins; __pthread_list_t __list; -# define __PTHREAD_MUTEX_HAVE_PREV 1 +# define __PTHREAD_MUTEX_HAVE_PREV 1 #else unsigned int __nusers; __extension__ union @@ -158,9 +160,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; @@ -174,9 +176,12 @@ typedef union unsigned int __writer_wakeup; unsigned int __nr_readers_queued; unsigned int __nr_writers_queued; + unsigned char __pad1; + unsigned char __pad2; + unsigned char __shared; /* FLAGS must stay at this position in the structure to maintain binary compatibility. */ - unsigned int __flags; + unsigned char __flags; int __writer; } __data; # endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h index 8123b418b..c7f121ba5 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h @@ -33,9 +33,6 @@ /* Value returned if `sem_open' failed. */ #define SEM_FAILED ((sem_t *) 0) -/* Maximum value the semaphore can have. */ -#define SEM_VALUE_MAX (2147483647) - typedef union { diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h index 1f2f481d6..66c02cbbd 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2006-2008, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Paul Mackerras , 2003. @@ -24,7 +24,7 @@ #include #include #include - +#include #ifndef __NR_futex # define __NR_futex 221 @@ -33,167 +33,262 @@ #define FUTEX_WAKE 1 #define FUTEX_REQUEUE 3 #define FUTEX_CMP_REQUEUE 4 +#define FUTEX_WAKE_OP 5 +#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1) +#define FUTEX_LOCK_PI 6 +#define FUTEX_UNLOCK_PI 7 +#define FUTEX_TRYLOCK_PI 8 +#define FUTEX_WAIT_BITSET 9 +#define FUTEX_WAKE_BITSET 10 +#define FUTEX_PRIVATE_FLAG 128 +#define FUTEX_CLOCK_REALTIME 256 + +#define FUTEX_BITSET_MATCH_ANY 0xffffffff + +/* 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 + +#if !defined NOT_IN_libc || defined IS_IN_rtld +/* In libc.so or ld.so all futexes are private. */ +# ifdef __ASSUME_PRIVATE_FUTEX +# define __lll_private_flag(fl, private) \ + ((fl) | FUTEX_PRIVATE_FLAG) +# else +# define __lll_private_flag(fl, private) \ + ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) +# endif +#else +# ifdef __ASSUME_PRIVATE_FUTEX +# define __lll_private_flag(fl, private) \ + (((fl) | FUTEX_PRIVATE_FLAG) ^ (private)) +# else +# define __lll_private_flag(fl, private) \ + (__builtin_constant_p (private) \ + ? ((private) == 0 \ + ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \ + : (fl)) \ + : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \ + & THREAD_GETMEM (THREAD_SELF, header.private_futex)))) +# endif +#endif -/* Initializer for compatibility lock. */ -#define LLL_MUTEX_LOCK_INITIALIZER (0) +#define lll_futex_wait(futexp, val, private) \ + lll_futex_timed_wait (futexp, val, NULL, private) -#define lll_futex_wait(futexp, val) \ +#define lll_futex_timed_wait(futexp, val, timespec, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ \ - __ret = INTERNAL_SYSCALL (futex, __err, 4, \ - (futexp), FUTEX_WAIT, (val), 0); \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), (timespec)); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ }) -#define lll_futex_timed_wait(futexp, val, timespec) \ +#define lll_futex_wake(futexp, nr, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ \ - __ret = INTERNAL_SYSCALL (futex, __err, 4, \ - (futexp), FUTEX_WAIT, (val), (timespec)); \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAKE, private), \ + (nr), 0); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ }) -#define lll_futex_wake(futexp, nr) \ +#define lll_robust_dead(futexv, private) \ + do \ + { \ + INTERNAL_SYSCALL_DECL (__err); \ + int *__futexp = &(futexv); \ + \ + atomic_or (__futexp, FUTEX_OWNER_DIED); \ + INTERNAL_SYSCALL (futex, __err, 4, __futexp, \ + __lll_private_flag (FUTEX_WAKE, private), 1, 0); \ + } \ + while (0) + +/* Returns non-zero if error happened, zero if success. */ +#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ \ - __ret = INTERNAL_SYSCALL (futex, __err, 4, \ - (futexp), FUTEX_WAKE, (nr), 0); \ - INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_CMP_REQUEUE, private),\ + (nr_wake), (nr_move), (mutex), (val)); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ }) /* Returns non-zero if error happened, zero if success. */ -#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val) \ +#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ \ - __ret = INTERNAL_SYSCALL (futex, __err, 6, \ - (futexp), FUTEX_CMP_REQUEUE, (nr_wake), \ - (nr_move), (mutex), (val)); \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_WAKE_OP, private), \ + (nr_wake), (nr_wake2), (futexp2), \ + FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ }) + #ifdef UP # define __lll_acq_instr "" # define __lll_rel_instr "" #else # define __lll_acq_instr "isync" -# define __lll_rel_instr "sync" +# ifdef _ARCH_PWR4 +/* + * Newer powerpc64 processors support the new "light weight" sync (lwsync) + * So if the build is using -mcpu=[power4,power5,power5+,970] we can + * safely use lwsync. + */ +# define __lll_rel_instr "lwsync" +# else +/* + * Older powerpc32 processors don't support the new "light weight" + * sync (lwsync). So the only safe option is to use normal sync + * for all powerpc32 applications. + */ +# define __lll_rel_instr "sync" +# endif #endif -/* Set *futex to 1 if it is 0, atomically. Returns the old value */ -#define __lll_trylock(futex) \ +/* Set *futex to ID if it is 0, atomically. Returns the old value */ +#define __lll_robust_trylock(futex, id) \ ({ int __val; \ - __asm __volatile ("1: lwarx %0,0,%2\n" \ + __asm __volatile ("1: lwarx %0,0,%2" MUTEX_HINT_ACQ "\n" \ " cmpwi 0,%0,0\n" \ " bne 2f\n" \ " stwcx. %3,0,%2\n" \ " bne- 1b\n" \ "2: " __lll_acq_instr \ : "=&r" (__val), "=m" (*futex) \ - : "r" (futex), "r" (1), "m" (*futex) \ + : "r" (futex), "r" (id), "m" (*futex) \ : "cr0", "memory"); \ __val; \ }) -#define lll_mutex_trylock(lock) __lll_trylock (&(lock)) +#define lll_robust_trylock(lock, id) __lll_robust_trylock (&(lock), id) + +/* Set *futex to 1 if it is 0, atomically. Returns the old value */ +#define __lll_trylock(futex) __lll_robust_trylock (futex, 1) + +#define lll_trylock(lock) __lll_trylock (&(lock)) /* Set *futex to 2 if it is 0, atomically. Returns the old value */ -#define __lll_cond_trylock(futex) \ - ({ int __val; \ - __asm __volatile ("1: lwarx %0,0,%2\n" \ - " cmpwi 0,%0,0\n" \ - " bne 2f\n" \ - " stwcx. %3,0,%2\n" \ - " bne- 1b\n" \ - "2: " __lll_acq_instr \ - : "=&r" (__val), "=m" (*futex) \ - : "r" (futex), "r" (2), "m" (*futex) \ - : "cr0", "memory"); \ - __val; \ - }) -#define lll_mutex_cond_trylock(lock) __lll_cond_trylock (&(lock)) +#define __lll_cond_trylock(futex) __lll_robust_trylock (futex, 2) +#define lll_cond_trylock(lock) __lll_cond_trylock (&(lock)) -extern void __lll_lock_wait (int *futex) attribute_hidden; -#define lll_mutex_lock(lock) \ +extern void __lll_lock_wait_private (int *futex) attribute_hidden; +extern void __lll_lock_wait (int *futex, int private) attribute_hidden; +extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden; + +#define lll_lock(lock, private) \ (void) ({ \ int *__futex = &(lock); \ if (__builtin_expect (atomic_compare_and_exchange_val_acq (__futex, 1, 0),\ 0) != 0) \ - __lll_lock_wait (__futex); \ + { \ + if (__builtin_constant_p (private) && (private) == LLL_PRIVATE) \ + __lll_lock_wait_private (__futex); \ + else \ + __lll_lock_wait (__futex, private); \ + } \ + }) + +#define lll_robust_lock(lock, id, private) \ + ({ \ + int *__futex = &(lock); \ + int __val = 0; \ + if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id, \ + 0), 0)) \ + __val = __lll_robust_lock_wait (__futex, private); \ + __val; \ }) -#define lll_mutex_cond_lock(lock) \ +#define lll_cond_lock(lock, private) \ (void) ({ \ int *__futex = &(lock); \ if (__builtin_expect (atomic_compare_and_exchange_val_acq (__futex, 2, 0),\ 0) != 0) \ - __lll_lock_wait (__futex); \ + __lll_lock_wait (__futex, private); \ + }) + +#define lll_robust_cond_lock(lock, id, private) \ + ({ \ + int *__futex = &(lock); \ + int __val = 0; \ + int __id = id | FUTEX_WAITERS; \ + if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, __id,\ + 0), 0)) \ + __val = __lll_robust_lock_wait (__futex, private); \ + __val; \ }) + extern int __lll_timedlock_wait - (int *futex, const struct timespec *) attribute_hidden; + (int *futex, const struct timespec *, int private) attribute_hidden; +extern int __lll_robust_timedlock_wait + (int *futex, const struct timespec *, int private) attribute_hidden; -#define lll_mutex_timedlock(lock, abstime) \ +#define lll_timedlock(lock, abstime, private) \ ({ \ int *__futex = &(lock); \ int __val = 0; \ if (__builtin_expect (atomic_compare_and_exchange_val_acq (__futex, 1, 0),\ 0) != 0) \ - __val = __lll_timedlock_wait (__futex, abstime); \ + __val = __lll_timedlock_wait (__futex, abstime, private); \ + __val; \ + }) + +#define lll_robust_timedlock(lock, abstime, id, private) \ + ({ \ + int *__futex = &(lock); \ + int __val = 0; \ + if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id, \ + 0), 0)) \ + __val = __lll_robust_timedlock_wait (__futex, abstime, private); \ __val; \ }) -#define lll_mutex_unlock(lock) \ +#define lll_unlock(lock, private) \ ((void) ({ \ 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, private); \ })) -#define lll_mutex_unlock_force(lock) \ +#define lll_robust_unlock(lock, private) \ ((void) ({ \ int *__futex = &(lock); \ - *__futex = 0; \ - __asm __volatile (__lll_rel_instr ::: "memory"); \ - lll_futex_wake (__futex, 1); \ + int __val = atomic_exchange_rel (__futex, 0); \ + if (__builtin_expect (__val & FUTEX_WAITERS, 0)) \ + lll_futex_wake (__futex, 1, private); \ })) -#define lll_mutex_islocked(futex) \ +#define lll_islocked(futex) \ (futex != 0) -/* Our internal lock implementation is identical to the binary-compatible - mutex implementation. */ - -/* Type for lock object. */ -typedef int lll_lock_t; - /* Initializers for lock. */ #define LLL_LOCK_INITIALIZER (0) #define LLL_LOCK_INITIALIZER_LOCKED (1) -extern int lll_unlock_wake_cb (int *__futex) attribute_hidden; - /* The states of a lock are: 0 - untaken 1 - taken by one user >1 - taken by more users */ -#define lll_trylock(lock) lll_mutex_trylock (lock) -#define lll_lock(lock) lll_mutex_lock (lock) -#define lll_unlock(lock) lll_mutex_unlock (lock) -#define lll_islocked(lock) lll_mutex_islocked (lock) - /* The kernel notifies a process which uses CLONE_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and is reset to zero @@ -202,7 +297,7 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden; 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 *) @@ -216,26 +311,4 @@ extern int __lll_timedwait_tid (int *, const struct timespec *) __res; \ }) - -/* Conditional variable handling. */ - -extern void __lll_cond_wait (pthread_cond_t *cond) - attribute_hidden; -extern int __lll_cond_timedwait (pthread_cond_t *cond, - const struct timespec *abstime) - attribute_hidden; -extern void __lll_cond_wake (pthread_cond_t *cond) - attribute_hidden; -extern void __lll_cond_broadcast (pthread_cond_t *cond) - attribute_hidden; - -#define lll_cond_wait(cond) \ - __lll_cond_wait (cond) -#define lll_cond_timedwait(cond, abstime) \ - __lll_cond_timedwait (cond, abstime) -#define lll_cond_wake(cond) \ - __lll_cond_wake (cond) -#define lll_cond_broadcast(cond) \ - __lll_cond_broadcast (cond) - #endif /* lowlevellock.h */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S index e19579e84..675a997e9 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S @@ -1,3 +1,9 @@ -#define RESET_PID -#include -#include +/* 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 +#else +# define RESET_PID +# include_next +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h index 0e6225624..88b24e7d9 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h @@ -1,5 +1,5 @@ /* Cancellable system call stubs. Linux/PowerPC version. - Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Franz Sirl , 2003. @@ -15,8 +15,8 @@ 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. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include #include @@ -30,7 +30,6 @@ # define PSEUDO(name, syscall_name, args) \ .section ".text"; \ ENTRY (name) \ - cfi_startproc; \ SINGLE_THREAD_P; \ bne- .Lpseudo_cancel; \ .type __##syscall_name##_nocancel,@function; \ @@ -45,7 +44,6 @@ mflr 9; \ stw 9,52(1); \ cfi_offset (lr, 4); \ - CGOTSETUP; \ DOCARGS_##args; /* save syscall args around CENABLE. */ \ CENABLE; \ stw 3,16(1); /* store CENABLE return value (MASK). */ \ @@ -59,11 +57,9 @@ lwz 4,52(1); \ lwz 0,12(1); /* restore CR/R3. */ \ lwz 3,8(1); \ - CGOTRESTORE; \ mtlr 4; \ mtcr 0; \ - addi 1,1,48; \ - cfi_endproc; + addi 1,1,48; # define DOCARGS_0 # define UNDOCARGS_0 @@ -86,9 +82,6 @@ # define DOCARGS_6 stw 8,40(1); DOCARGS_5 # define UNDOCARGS_6 lwz 8,40(1); UNDOCARGS_5 -# define CGOTSETUP -# define CGOTRESTORE - # ifdef IS_IN_libpthread # define CENABLE bl __pthread_enable_asynccancel@local # define CDISABLE bl __pthread_disable_asynccancel@local @@ -96,20 +89,8 @@ # define CENABLE bl __libc_enable_asynccancel@local # define CDISABLE bl __libc_disable_asynccancel@local # elif defined IS_IN_librt -# define CENABLE bl JUMPTARGET(__librt_enable_asynccancel) -# define CDISABLE bl JUMPTARGET(__librt_disable_asynccancel) -# if defined HAVE_AS_REL16 && defined __PIC__ -# undef CGOTSETUP -# define CGOTSETUP \ - bcl 20,31,1f; \ - 1: stw 30,44(1); \ - mflr 30; \ - addis 30,30,_GLOBAL_OFFSET_TABLE-1b@ha; \ - addi 30,30,_GLOBAL_OFFSET_TABLE-1b@l -# undef CGOTRESTORE -# define CGOTRESTORE \ - lwz 30,44(1) -# endif +# define CENABLE bl __librt_enable_asynccancel@local +# define CDISABLE bl __librt_disable_asynccancel@local # else # error Unsupported library # endif @@ -130,3 +111,9 @@ # define NO_CANCELLATION 1 #endif + +#ifndef __ASSEMBLER__ +# define RTLD_SINGLE_THREAD_P \ + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ + header.multiple_threads) == 0, 1) +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S index b7e2cf6e7..eed2a8f1a 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S @@ -53,5 +53,5 @@ ENTRY (__vfork) PSEUDO_RET PSEUDO_END (__vfork) -hidden_def (__vfork) +libc_hidden_def (__vfork) weak_alias (__vfork, vfork) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions deleted file mode 100644 index 3b111ddb5..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions +++ /dev/null @@ -1,7 +0,0 @@ -librt { - GLIBC_2.3.3 { - # Changed timer_t. - timer_create; timer_delete; timer_getoverrun; timer_gettime; - timer_settime; - } -} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S index f87adf473..675a997e9 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S @@ -1,3 +1,9 @@ -#define RESET_PID -#include -#include +/* 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 +#else +# define RESET_PID +# include_next +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h index 226aaafdc..707765ab5 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h @@ -1,5 +1,5 @@ /* Cancellable system call stubs. Linux/PowerPC64 version. - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Franz Sirl , 2003. @@ -15,8 +15,8 @@ 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. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include #include @@ -36,7 +36,6 @@ # define PSEUDO(name, syscall_name, args) \ .section ".text"; \ ENTRY (name) \ - cfi_startproc; \ SINGLE_THREAD_P; \ bne- .Lpseudo_cancel; \ .type DASHDASHPFX(syscall_name##_nocancel),@function; \ @@ -66,8 +65,7 @@ ld 3,64(1); \ mtlr 9; \ mtcr 0; \ - addi 1,1,128; \ - cfi_endproc; + addi 1,1,128; # define DOCARGS_0 # define UNDOCARGS_0 @@ -119,3 +117,9 @@ # define NO_CANCELLATION 1 #endif + +#ifndef __ASSEMBLER__ +# define RTLD_SINGLE_THREAD_P \ + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ + header.multiple_threads) == 0, 1) +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S index 018132136..26885bb95 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S @@ -51,5 +51,5 @@ ENTRY (__vfork) PSEUDO_RET PSEUDO_END (__vfork) -hidden_def (__vfork) +libc_hidden_def (__vfork) weak_alias (__vfork, vfork) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c index e1afff8a3..969078094 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c +++ b/libpthread/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_futex_wake (once_control, INT_MAX, LLL_PRIVATE); } @@ -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_futex_wait (once_control, oldval, LLL_PRIVATE); } @@ -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_futex_wake (once_control, INT_MAX, LLL_PRIVATE); return 0; } diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c new file mode 100644 index 000000000..90f2dc67c --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c @@ -0,0 +1,29 @@ +/* pthread_spin_unlock -- unlock a spin lock. PowerPC version. + Copyright (C) 2007 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 + 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 "pthreadP.h" +#include + +int +pthread_spin_unlock (pthread_spinlock_t *lock) +{ + __asm __volatile (__lll_rel_instr ::: "memory"); + *lock = 0; + return 0; +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c index 06b3bd0ab..0082c570a 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c +++ b/libpthread/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. @@ -27,15 +27,20 @@ int __new_sem_post (sem_t *sem) { - int *futex = (int *) sem; + struct new_sem *isem = (struct new_sem *) sem; __asm __volatile (__lll_rel_instr ::: "memory"); - int nr = atomic_increment_val (futex); - int err = lll_futex_wake (futex, nr); - if (__builtin_expect (err, 0) < 0) + atomic_increment (&isem->value); + __asm __volatile (__lll_acq_instr ::: "memory"); + if (isem->nwaiters > 0) { - __set_errno (-err); - return -1; + int err = lll_futex_wake (&isem->value, 1, + isem->private ^ FUTEX_PRIVATE_FLAG); + if (__builtin_expect (err, 0) < 0) + { + __set_errno (-err); + return -1; + } } return 0; } -- cgit v1.2.3