summaryrefslogtreecommitdiff
path: root/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux/powerpc')
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/Versions5
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h15
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h3
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h251
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h37
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions7
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h16
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c8
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c29
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c19
14 files changed, 259 insertions, 159 deletions
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 <paulus@au.ibm.com>, 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 <paulus@au.ibm.com>, 2003.
@@ -24,7 +24,7 @@
#include <sys/param.h>
#include <bits/pthreadtypes.h>
#include <atomic.h>
-
+#include <kernel-features.h>
#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 <tcb-offsets.h>
-#include <sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S>
+/* 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 <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#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 <Franz.Sirl-kernel@lauterbach.com>, 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 <sysdep.h>
#include <tls.h>
@@ -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 <tcb-offsets.h>
-#include <sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S>
+/* 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 <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#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 <Franz.Sirl-kernel@lauterbach.com>, 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 <sysdep.h>
#include <tls.h>
@@ -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 <paulus@au.ibm.com>, 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 <lowlevellock.h>
+
+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 <paulus@au.ibm.com>, 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;
}