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 --- .../sysdeps/unix/sysv/linux/sparc/Makefile.arch | 3 +- .../nptl/sysdeps/unix/sysv/linux/sparc/Versions | 6 - .../sysdeps/unix/sysv/linux/sparc/bits/local_lim.h | 13 +- .../unix/sysv/linux/sparc/bits/pthreadtypes.h | 13 +- .../sysdeps/unix/sysv/linux/sparc/bits/semaphore.h | 3 - .../sysdeps/unix/sysv/linux/sparc/internaltypes.h | 34 +++++ .../sysdeps/unix/sysv/linux/sparc/lowlevellock.c | 37 ++--- .../sysdeps/unix/sysv/linux/sparc/lowlevellock.h | 166 +++++++++++++-------- .../sysdeps/unix/sysv/linux/sparc/not-cancel.h | 1 + .../sysv/linux/sparc/pthread_barrier_destroy.c | 45 ++++++ .../unix/sysv/linux/sparc/pthread_barrier_init.c | 55 +++++++ .../sysdeps/unix/sysv/linux/sparc/pthread_once.c | 8 +- .../nptl/sysdeps/unix/sysv/linux/sparc/sem_init.c | 57 +++++++ .../linux/sparc/sparc32/pthread_barrier_wait.c | 94 ++++++++++++ .../unix/sysv/linux/sparc/sparc32/sem_post.c | 55 +++++++ .../unix/sysv/linux/sparc/sparc32/sem_timedwait.c | 148 ++++++++++++++++++ .../unix/sysv/linux/sparc/sparc32/sem_trywait.c | 54 +++++++ .../unix/sysv/linux/sparc/sparc32/sem_wait.c | 127 ++++++++++++++++ .../unix/sysv/linux/sparc/sparc32/sysdep-cancel.h | 91 +++++------ .../sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S | 2 +- .../sysdeps/unix/sysv/linux/sparc/sparc64/Versions | 7 - 21 files changed, 867 insertions(+), 152 deletions(-) delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Versions create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/internaltypes.h create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/not-cancel.h create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_destroy.c create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_init.c create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sem_init.c create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/Versions (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux/sparc') diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch index b54731075..b6df6dcc1 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch @@ -6,7 +6,8 @@ # libpthread_SSRC = pt-vfork.S clone.S -libpthread_CSRC = pthread_once.c lowlevellock.c +libpthread_CSRC = pthread_once.c lowlevellock.c \ + pthred_barrier_init.c pthread_barrier_wait.c pthread_barrier_destroy.c libc_a_CSRC = fork.c libc-lowlevellock.c libc_a_SSRC = clone.S vfork.S diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Versions b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Versions deleted file mode 100644 index d10277248..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Versions +++ /dev/null @@ -1,6 +0,0 @@ -libpthread { - GLIBC_2.3.3 { - # Changed PTHREAD_STACK_MIN. - pthread_attr_setstack; pthread_attr_setstacksize; - } -} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h index e082ea8f0..6e356031d 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h @@ -1,5 +1,5 @@ /* Minimum guaranteed maximum values for system limits. Linux/SPARC version. - Copyright (C) 1993-1998,2000,2002,2003,2004 Free Software Foundation, Inc. + Copyright (C) 1993-1998,2000,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,6 +31,9 @@ #ifndef OPEN_MAX # define __undef_OPEN_MAX #endif +#ifndef ARG_MAX +# define __undef_ARG_MAX +#endif /* The kernel sources contain a file with all the needed information. */ #include @@ -50,6 +53,11 @@ # undef OPEN_MAX # undef __undef_OPEN_MAX #endif +/* Have to remove ARG_MAX? */ +#ifdef __undef_ARG_MAX +# undef ARG_MAX +# undef __undef_ARG_MAX +#endif /* The number of data keys per process. */ #define _POSIX_THREAD_KEYS_MAX 128 @@ -87,3 +95,6 @@ /* Maximum message queue priority level. */ #define MQ_PRIO_MAX 32768 + +/* Maximum value the semaphore can have. */ +#define SEM_VALUE_MAX (2147483647) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h index 459d1ca79..faf058486 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h @@ -1,5 +1,5 @@ /* Machine-specific pthread type layouts. SPARC 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 Jakub Jelinek , 2003. @@ -90,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 @@ -160,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; @@ -176,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/sparc/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/semaphore.h index 7f3a32832..8fd7d344e 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/semaphore.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/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/sparc/internaltypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/internaltypes.h new file mode 100644 index 000000000..4f400a3fe --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/internaltypes.h @@ -0,0 +1,34 @@ +#ifndef _INTERNALTYPES_H +#include "../internaltypes.h" + +union sparc_pthread_barrier +{ + struct pthread_barrier b; + struct sparc_pthread_barrier_s + { + unsigned int curr_event; + int lock; + unsigned int left; + unsigned int init_count; + unsigned char left_lock; + unsigned char pshared; + } s; +}; + +struct sparc_new_sem +{ + unsigned int value; + unsigned char lock; + unsigned char private; + unsigned char pad[2]; + unsigned long int nwaiters; +}; + +struct sparc_old_sem +{ + unsigned int value; + unsigned char lock; + unsigned char private; +}; + +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.c index e9ec4df1e..80b0e7663 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.c @@ -24,23 +24,36 @@ #include -/* These functions don't get included in libc.so */ void -__lll_lock_wait (int *futex) +__lll_lock_wait_private (int *futex) { do { int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1); if (oldval != 0) - lll_futex_wait (futex, 2); + lll_futex_wait (futex, 2, LLL_PRIVATE); } while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0); } +/* These functions don't get included in libc.so */ #ifdef IS_IN_libpthread +void +__lll_lock_wait (int *futex, int private) +{ + do + { + int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1); + if (oldval != 0) + lll_futex_wait (futex, 2, private); + } + while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0); +} + + int -__lll_timedlock_wait (int *futex, const struct timespec *abstime) +__lll_timedlock_wait (int *futex, const struct timespec *abstime, int private) { /* Reject invalid timeouts. */ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) @@ -70,25 +83,13 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime) /* Wait. */ int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1); if (oldval != 0) - lll_futex_timed_wait (futex, 2, &rt); + lll_futex_timed_wait (futex, 2, &rt, private); } while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0); return 0; } -int -lll_unlock_wake_cb(int* futex) -{ - int val = atomic_exchange_24_rel(futex, 0); - - if( __builtin_expect( val > 1, 0 ) ) { - lll_futex_wake( futex, 1 ); - } - - return 0; -} - int __lll_timedwait_tid (int *tidp, const struct timespec *abstime) @@ -122,7 +123,7 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime) /* Wait until thread terminates. The kernel so far does not use the private futex operations for this. */ - if (lll_futex_timed_wait (tidp, tid, &rt) == -ETIMEDOUT) + if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT) return ETIMEDOUT; } diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h index 4db6fb0b4..a43f6b668 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek , 2003. @@ -24,7 +25,7 @@ #include #include #include -#include +#include #define FUTEX_WAIT 0 @@ -33,62 +34,107 @@ #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) \ - lll_futex_timed_wait (futexp, val, NULL) +#define lll_futex_wait(futexp, val, private) \ + lll_futex_timed_wait (futexp, val, NULL, private) -#define lll_futex_timed_wait(futexp, val, timespec) \ +#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), (timespec)); \ + \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), (timespec)); \ __ret; \ }) -#define lll_futex_wake(futexp, nr) \ +#define lll_futex_wake(futexp, nr, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ + \ __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ - FUTEX_WAKE, (nr), 0); \ + __lll_private_flag (FUTEX_WAKE, private), \ + (nr), 0); \ __ret; \ }) /* Returns non-zero if error happened, zero if success. */ -#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val) \ +#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ + \ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ - FUTEX_CMP_REQUEUE, (nr_wake), (nr_move), (mutex), (val)); \ + __lll_private_flag (FUTEX_CMP_REQUEUE, private),\ + (nr_wake), (nr_move), (mutex), (val)); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ }) -#define lll_robust_dead(futexv) \ +#define lll_robust_dead(futexv, private) \ do \ { \ int *__futexp = &(futexv); \ atomic_or (__futexp, FUTEX_OWNER_DIED); \ - lll_futex_wake (__futexp, 1); \ + lll_futex_wake (__futexp, 1, private); \ } \ while (0) /* Returns non-zero if error happened, zero if success. */ #ifdef __sparc32_atomic_do_lock /* Avoid FUTEX_WAKE_OP if supporting pre-v9 CPUs. */ -# define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) 1 +# define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) 1 #else -# 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 __ret; \ \ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ - FUTEX_WAKE_OP, \ + __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); \ @@ -101,7 +147,7 @@ __lll_trylock (int *futex) { return atomic_compare_and_exchange_val_24_acq (futex, 1, 0) != 0; } -#define lll_mutex_trylock(futex) __lll_trylock (&(futex)) +#define lll_trylock(futex) __lll_trylock (&(futex)) static inline int __attribute__ ((always_inline)) @@ -109,7 +155,7 @@ __lll_cond_trylock (int *futex) { return atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0; } -#define lll_mutex_cond_trylock(futex) __lll_cond_trylock (&(futex)) +#define lll_cond_trylock(futex) __lll_cond_trylock (&(futex)) static inline int __attribute__ ((always_inline)) @@ -121,116 +167,108 @@ __lll_robust_trylock (int *futex, int id) __lll_robust_trylock (&(futex), id) -extern void __lll_lock_wait (int *futex) attribute_hidden; -extern int __lll_robust_lock_wait (int *futex) attribute_hidden; +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; static inline void __attribute__ ((always_inline)) -__lll_lock (int *futex) +__lll_lock (int *futex, int private) { int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0); if (__builtin_expect (val != 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_mutex_lock(futex) __lll_lock (&(futex)) +#define lll_lock(futex, private) __lll_lock (&(futex), private) static inline int __attribute__ ((always_inline)) -__lll_robust_lock (int *futex, int id) +__lll_robust_lock (int *futex, int id, int private) { int result = 0; if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0) - result = __lll_robust_lock_wait (futex); + result = __lll_robust_lock_wait (futex, private); return result; } -#define lll_robust_lock(futex, id) \ - __lll_robust_lock (&(futex), id) +#define lll_robust_lock(futex, id, private) \ + __lll_robust_lock (&(futex), id, private) static inline void __attribute__ ((always_inline)) -__lll_cond_lock (int *futex) +__lll_cond_lock (int *futex, int private) { int val = atomic_compare_and_exchange_val_24_acq (futex, 2, 0); if (__builtin_expect (val != 0, 0)) - __lll_lock_wait (futex); + __lll_lock_wait (futex, private); } -#define lll_mutex_cond_lock(futex) __lll_cond_lock (&(futex)) +#define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private) -#define lll_robust_cond_lock(futex, id) \ - __lll_robust_lock (&(futex), (id) | FUTEX_WAITERS) +#define lll_robust_cond_lock(futex, id, private) \ + __lll_robust_lock (&(futex), (id) | FUTEX_WAITERS, private) -extern int __lll_timedlock_wait (int *futex, const struct timespec *) attribute_hidden; -extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *) attribute_hidden; +extern int __lll_timedlock_wait (int *futex, const struct timespec *, + int private) attribute_hidden; +extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *, + int private) attribute_hidden; static inline int __attribute__ ((always_inline)) -__lll_timedlock (int *futex, const struct timespec *abstime) +__lll_timedlock (int *futex, const struct timespec *abstime, int private) { int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0); int result = 0; if (__builtin_expect (val != 0, 0)) - result = __lll_timedlock_wait (futex, abstime); + result = __lll_timedlock_wait (futex, abstime, private); return result; } -#define lll_mutex_timedlock(futex, abstime) \ - __lll_timedlock (&(futex), abstime) +#define lll_timedlock(futex, abstime, private) \ + __lll_timedlock (&(futex), abstime, private) static inline int __attribute__ ((always_inline)) __lll_robust_timedlock (int *futex, const struct timespec *abstime, - int id) + int id, int private) { int result = 0; if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0) - result = __lll_robust_timedlock_wait (futex, abstime); + result = __lll_robust_timedlock_wait (futex, abstime, private); return result; } -#define lll_robust_timedlock(futex, abstime, id) \ - __lll_robust_timedlock (&(futex), abstime, id) +#define lll_robust_timedlock(futex, abstime, id, private) \ + __lll_robust_timedlock (&(futex), abstime, id, private) -#define lll_mutex_unlock(lock) \ +#define lll_unlock(lock, private) \ ((void) ({ \ int *__futex = &(lock); \ int __val = atomic_exchange_24_rel (__futex, 0); \ if (__builtin_expect (__val > 1, 0)) \ - lll_futex_wake (__futex, 1); \ + lll_futex_wake (__futex, 1, private); \ })) -#define lll_robust_unlock(lock) \ +#define lll_robust_unlock(lock, private) \ ((void) ({ \ 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, private); \ })) -#define lll_mutex_islocked(futex) \ +#define lll_islocked(futex) \ (futex != 0) -/* We have a separate internal lock implementation which is not tied - to binary compatibility. */ - -/* 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; - -#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 with 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 @@ -240,7 +278,7 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden; { \ __typeof (tid) __tid; \ while ((__tid = (tid)) != 0) \ - lll_futex_wait (&(tid), __tid); \ + lll_futex_wait (&(tid), __tid, LLL_SHARED); \ } \ while (0) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/not-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/not-cancel.h new file mode 100644 index 000000000..acf1a617e --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/not-cancel.h @@ -0,0 +1 @@ +#include "../i386/not-cancel.h" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_destroy.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_destroy.c new file mode 100644 index 000000000..ca96379c9 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_destroy.c @@ -0,0 +1,45 @@ +/* Copyright (C) 2002, 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2002. + + 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 +#include "pthreadP.h" +#include + +int +pthread_barrier_destroy ( + pthread_barrier_t *barrier) +{ + union sparc_pthread_barrier *ibarrier; + int result = EBUSY; + + ibarrier = (union sparc_pthread_barrier *) barrier; + + int private = ibarrier->s.pshared ? LLL_SHARED : LLL_PRIVATE; + + lll_lock (ibarrier->b.lock, private); + + if (__builtin_expect (ibarrier->b.left == ibarrier->b.init_count, 1)) + /* The barrier is not used anymore. */ + result = 0; + else + /* Still used, return with an error. */ + lll_unlock (ibarrier->b.lock, private); + + return result; +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_init.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_init.c new file mode 100644 index 000000000..6ca472778 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_init.c @@ -0,0 +1,55 @@ +/* Copyright (C) 2002, 2006, 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2002. + + 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 +#include "pthreadP.h" +#include + +int +pthread_barrier_init ( + pthread_barrier_t *barrier, + const pthread_barrierattr_t *attrm, + unsigned int count) +{ + union sparc_pthread_barrier *ibarrier; + + if (__builtin_expect (count == 0, 0)) + return EINVAL; + + struct pthread_barrierattr *iattr = (struct pthread_barrierattr *) attr; + if (iattr != NULL) + { + if (iattr->pshared != PTHREAD_PROCESS_PRIVATE + && __builtin_expect (iattr->pshared != PTHREAD_PROCESS_SHARED, 0)) + /* Invalid attribute. */ + return EINVAL; + } + + ibarrier = (union sparc_pthread_barrier *) barrier; + + /* Initialize the individual fields. */ + ibarrier->b.lock = LLL_LOCK_INITIALIZER; + ibarrier->b.left = count; + ibarrier->b.init_count = count; + ibarrier->b.curr_event = 0; + ibarrier->s.left_lock = 0; + ibarrier->s.pshared = (iattr && iattr->pshared == PTHREAD_PROCESS_SHARED); + + return 0; +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c index 3b07cc127..22e2dd3c0 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/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 Jakub Jelinek , 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); } @@ -65,7 +65,7 @@ __pthread_once (once_control, init_routine) if (((oldval ^ newval) & -4) == 0) { /* Same generation, some other thread was faster. Wait. */ - lll_futex_wait (once_control, newval); + lll_futex_wait (once_control, newval, LLL_PRIVATE); continue; } } @@ -84,7 +84,7 @@ __pthread_once (once_control, init_routine) 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); break; } diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sem_init.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sem_init.c new file mode 100644 index 000000000..f694b5e93 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sem_init.c @@ -0,0 +1,57 @@ +/* Copyright (C) 2002, 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2002. + + 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 +#include +#include +#include +#include "semaphoreP.h" +#include + + +int +__new_sem_init (sem, pshared, value) + sem_t *sem; + int pshared; + unsigned int value; +{ + /* Parameter sanity check. */ + if (__builtin_expect (value > SEM_VALUE_MAX, 0)) + { + __set_errno (EINVAL); + return -1; + } + + /* Map to the internal type. */ + struct sparc_new_sem *isem = (struct sparc_new_sem *) sem; + + /* Use the values the user provided. */ + memset (isem, '\0', sizeof (*isem)); + isem->value = value; +#ifdef __ASSUME_PRIVATE_FUTEX + isem->private = pshared ? 0 : FUTEX_PRIVATE_FLAG; +#else + isem->private = pshared ? 0 : THREAD_GETMEM (THREAD_SELF, + header.private_futex); +#endif + + return 0; +} +weak_alias(__new_sem_init, sem_init) + diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c new file mode 100644 index 000000000..302d1b371 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c @@ -0,0 +1,94 @@ +/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Martin Schwidefsky , 2003. + + 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 +#include +#include +#include + +/* Wait on barrier. */ +int +pthread_barrier_wait ( + pthread_barrier_t *barrier) +{ + union sparc_pthread_barrier *ibarrier + = (union sparc_pthread_barrier *) barrier; + int result = 0; + int private = ibarrier->s.pshared ? LLL_SHARED : LLL_PRIVATE; + + /* Make sure we are alone. */ + lll_lock (ibarrier->b.lock, private); + + /* One more arrival. */ + --ibarrier->b.left; + + /* Are these all? */ + if (ibarrier->b.left == 0) + { + /* Yes. Increment the event counter to avoid invalid wake-ups and + tell the current waiters that it is their turn. */ + ++ibarrier->b.curr_event; + + /* Wake up everybody. */ + lll_futex_wake (&ibarrier->b.curr_event, INT_MAX, private); + + /* This is the thread which finished the serialization. */ + result = PTHREAD_BARRIER_SERIAL_THREAD; + } + else + { + /* The number of the event we are waiting for. The barrier's event + number must be bumped before we continue. */ + unsigned int event = ibarrier->b.curr_event; + + /* Before suspending, make the barrier available to others. */ + lll_unlock (ibarrier->b.lock, private); + + /* Wait for the event counter of the barrier to change. */ + do + lll_futex_wait (&ibarrier->b.curr_event, event, private); + while (event == ibarrier->b.curr_event); + } + + /* Make sure the init_count is stored locally or in a register. */ + unsigned int init_count = ibarrier->b.init_count; + + /* If this was the last woken thread, unlock. */ + if (__atomic_is_v9 || ibarrier->s.pshared == 0) + { + if (atomic_increment_val (&ibarrier->b.left) == init_count) + /* We are done. */ + lll_unlock (ibarrier->b.lock, private); + } + else + { + unsigned int left; + /* Slightly more complicated. On pre-v9 CPUs, atomic_increment_val + is only atomic for threads within the same process, not for + multiple processes. */ + __sparc32_atomic_do_lock24 (&ibarrier->s.left_lock); + left = ++ibarrier->b.left; + __sparc32_atomic_do_unlock24 (&ibarrier->s.left_lock); + if (left == init_count) + /* We are done. */ + lll_unlock (ibarrier->b.lock, private); + } + + return result; +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c new file mode 100644 index 000000000..940728eeb --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c @@ -0,0 +1,55 @@ +/* sem_post -- post to a POSIX semaphore. SPARC version. + Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2003. + + 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 +#include +#include +#include +#include + +int +__new_sem_post (sem_t *sem) +{ + struct sparc_new_sem *isem = (struct sparc_new_sem *) sem; + int nr; + + if (__atomic_is_v9) + nr = atomic_increment_val (&isem->value); + else + { + __sparc32_atomic_do_lock24 (&isem->lock); + nr = ++(isem->value); + __sparc32_atomic_do_unlock24 (&isem->lock); + } + atomic_full_barrier (); + if (isem->nwaiters > 0) + { + 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; +} +weak_alias(__new_sem_post, sem_post) + diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c new file mode 100644 index 000000000..aa5bd80ed --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c @@ -0,0 +1,148 @@ +/* sem_timedwait -- wait on a semaphore. SPARC version. + Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Paul Mackerras , 2003. + + 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 +#include +#include +#include +#include + +#include + + +extern void __sem_wait_cleanup (void *arg) attribute_hidden; + + +int +sem_timedwait (sem_t *sem, const struct timespec *abstime) +{ + struct sparc_new_sem *isem = (struct sparc_new_sem *) sem; + int err; + int val; + + if (__atomic_is_v9) + val = atomic_decrement_if_positive (&isem->value); + else + { + __sparc32_atomic_do_lock24 (&isem->lock); + val = isem->value; + if (val > 0) + isem->value = val - 1; + __sparc32_atomic_do_unlock24 (&isem->lock); + } + + if (val > 0) + return 0; + + if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) + { + __set_errno (EINVAL); + return -1; + } + + if (__atomic_is_v9) + atomic_increment (&isem->nwaiters); + else + { + __sparc32_atomic_do_lock24 (&isem->lock); + isem->nwaiters++; + __sparc32_atomic_do_unlock24 (&isem->lock); + } + + pthread_cleanup_push (__sem_wait_cleanup, isem); + + while (1) + { + struct timeval tv; + struct timespec rt; + int sec, nsec; + + /* Get the current time. */ + __gettimeofday (&tv, NULL); + + /* Compute relative timeout. */ + sec = abstime->tv_sec - tv.tv_sec; + nsec = abstime->tv_nsec - tv.tv_usec * 1000; + if (nsec < 0) + { + nsec += 1000000000; + --sec; + } + + /* Already timed out? */ + err = -ETIMEDOUT; + if (sec < 0) + { + __set_errno (ETIMEDOUT); + err = -1; + break; + } + + /* Do wait. */ + rt.tv_sec = sec; + rt.tv_nsec = nsec; + + /* Enable asynchronous cancellation. Required by the standard. */ + int oldtype = __pthread_enable_asynccancel (); + + err = lll_futex_timed_wait (&isem->value, 0, &rt, + isem->private ^ FUTEX_PRIVATE_FLAG); + + /* Disable asynchronous cancellation. */ + __pthread_disable_asynccancel (oldtype); + + if (err != 0 && err != -EWOULDBLOCK) + { + __set_errno (-err); + err = -1; + break; + } + + if (__atomic_is_v9) + val = atomic_decrement_if_positive (&isem->value); + else + { + __sparc32_atomic_do_lock24 (&isem->lock); + val = isem->value; + if (val > 0) + isem->value = val - 1; + __sparc32_atomic_do_unlock24 (&isem->lock); + } + + if (val > 0) + { + err = 0; + break; + } + } + + pthread_cleanup_pop (0); + + if (__atomic_is_v9) + atomic_decrement (&isem->nwaiters); + else + { + __sparc32_atomic_do_lock24 (&isem->lock); + isem->nwaiters--; + __sparc32_atomic_do_unlock24 (&isem->lock); + } + + return err; +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c new file mode 100644 index 000000000..d4e893805 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c @@ -0,0 +1,54 @@ +/* sem_trywait -- wait on a semaphore. SPARC version. + Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Paul Mackerras , 2003. + + 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 +#include +#include +#include +#include + + +int +__new_sem_trywait (sem_t *sem) +{ + struct sparc_old_sem *isem = (struct sparc_old_sem *) sem; + int val; + + if (isem->value > 0) + { + if (__atomic_is_v9) + val = atomic_decrement_if_positive (&isem->value); + else + { + __sparc32_atomic_do_lock24 (&isem->lock); + val = isem->value; + if (val > 0) + isem->value = val - 1; + __sparc32_atomic_do_unlock24 (&isem->lock); + } + if (val > 0) + return 0; + } + + __set_errno (EAGAIN); + return -1; +} +weak_alias(__new_sem_trywait, sem_trywait) + diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c new file mode 100644 index 000000000..cfe04a802 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c @@ -0,0 +1,127 @@ +/* sem_wait -- wait on a semaphore. Generic futex-using version. + Copyright (C) 2003, 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Paul Mackerras , 2003. + + 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 +#include +#include +#include +#include + +#include + + +void +attribute_hidden +__sem_wait_cleanup (void *arg) +{ + struct sparc_new_sem *isem = (struct sparc_new_sem *) arg; + + if (__atomic_is_v9) + atomic_decrement (&isem->nwaiters); + else + { + __sparc32_atomic_do_lock24 (&isem->lock); + isem->nwaiters--; + __sparc32_atomic_do_unlock24 (&isem->lock); + } +} + + +int +__new_sem_wait (sem_t *sem) +{ + struct sparc_new_sem *isem = (struct sparc_new_sem *) sem; + int err; + int val; + + if (__atomic_is_v9) + val = atomic_decrement_if_positive (&isem->value); + else + { + __sparc32_atomic_do_lock24 (&isem->lock); + val = isem->value; + if (val > 0) + isem->value = val - 1; + else + isem->nwaiters++; + __sparc32_atomic_do_unlock24 (&isem->lock); + } + + if (val > 0) + return 0; + + if (__atomic_is_v9) + atomic_increment (&isem->nwaiters); + else + /* Already done above while still holding isem->lock. */; + + pthread_cleanup_push (__sem_wait_cleanup, isem); + + while (1) + { + /* Enable asynchronous cancellation. Required by the standard. */ + int oldtype = __pthread_enable_asynccancel (); + + err = lll_futex_wait (&isem->value, 0, + isem->private ^ FUTEX_PRIVATE_FLAG); + + /* Disable asynchronous cancellation. */ + __pthread_disable_asynccancel (oldtype); + + if (err != 0 && err != -EWOULDBLOCK) + { + __set_errno (-err); + err = -1; + break; + } + + if (__atomic_is_v9) + val = atomic_decrement_if_positive (&isem->value); + else + { + __sparc32_atomic_do_lock24 (&isem->lock); + val = isem->value; + if (val > 0) + isem->value = val - 1; + __sparc32_atomic_do_unlock24 (&isem->lock); + } + + if (val > 0) + { + err = 0; + break; + } + } + + pthread_cleanup_pop (0); + + if (__atomic_is_v9) + atomic_decrement (&isem->nwaiters); + else + { + __sparc32_atomic_do_lock24 (&isem->lock); + isem->nwaiters--; + __sparc32_atomic_do_unlock24 (&isem->lock); + } + + return err; +} +weak_alias(__new_sem_wait, sem_wait) + diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h index ad650d040..1f55bd623 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek , 2002. @@ -26,47 +26,48 @@ #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt # undef PSEUDO -# define PSEUDO(name, syscall_name, args) \ - .text; \ - .globl __syscall_error; \ -ENTRY(name) \ - ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;\ - cmp %g1, 0; \ - bne 1f; \ -.type __##syscall_name##_nocancel,@function; \ -.globl __##syscall_name##_nocancel; \ -__##syscall_name##_nocancel: \ - mov SYS_ify(syscall_name), %g1; \ - ta 0x10; \ - bcc 8f; \ - mov %o7, %g1; \ - call __syscall_error; \ - mov %g1, %o7; \ -8: jmpl %o7 + 8, %g0; \ - nop; \ -.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;\ -1: save %sp, -96, %sp; \ - cfi_def_cfa_register(%fp); \ - cfi_window_save; \ - cfi_register(%o7, %i7); \ - CENABLE; \ - nop; \ - mov %o0, %l0; \ - COPY_ARGS_##args \ - mov SYS_ify(syscall_name), %g1; \ - ta 0x10; \ - bcc 1f; \ - mov %o0, %l1; \ - CDISABLE; \ - mov %l0, %o0; \ - call __syscall_error; \ - mov %l1, %o0; \ - b 2f; \ - mov -1, %l1; \ -1: CDISABLE; \ - mov %l0, %o0; \ -2: jmpl %i7 + 8, %g0; \ - restore %g0, %l1, %o0; +# define PSEUDO(name, syscall_name, args) \ + .text; \ + .globl __syscall_error; \ +ENTRY(name) \ + ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;\ + cmp %g1, 0; \ + bne 1f; \ +.type __##syscall_name##_nocancel,@function; \ +.globl __##syscall_name##_nocancel; \ +__##syscall_name##_nocancel: \ + mov SYS_ify(syscall_name), %g1; \ + ta 0x10; \ + bcc 8f; \ + mov %o7, %g1; \ + call __syscall_error; \ + mov %g1, %o7; \ +8: jmpl %o7 + 8, %g0; \ + nop; \ +.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;\ +1: save %sp, -96, %sp; \ + cfi_def_cfa_register(%fp); \ + cfi_window_save; \ + cfi_register(%o7, %i7); \ + CENABLE; \ + nop; \ + mov %o0, %l0; \ + COPY_ARGS_##args \ + mov SYS_ify(syscall_name), %g1; \ + ta 0x10; \ + bcc 1f; \ + mov %o0, %l1; \ + CDISABLE; \ + mov %l0, %o0; \ + call __syscall_error; \ + mov %l1, %o0; \ + b 2f; \ + mov -1, %l1; \ +1: CDISABLE; \ + mov %l0, %o0; \ +2: jmpl %i7 + 8, %g0; \ + restore %g0, %l1, %o0; + # ifdef IS_IN_libpthread # define CENABLE call __pthread_enable_asynccancel @@ -103,3 +104,9 @@ __##syscall_name##_nocancel: \ # 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/sparc/sparc32/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S index 1a3827789..a8e4dd5a4 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S @@ -45,5 +45,5 @@ ENTRY(__vfork) nop END(__vfork) -hidden_def (vfork) +libc_hidden_def (__vfork) weak_alias (__vfork, vfork) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/Versions b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/Versions deleted file mode 100644 index 3b111ddb5..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/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; - } -} -- cgit v1.2.3