diff options
Diffstat (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux/powerpc')
24 files changed, 1295 insertions, 0 deletions
| diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/Makefile new file mode 100644 index 000000000..e98c9bd86 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/Makefile @@ -0,0 +1,2 @@ +# pull in __syscall_error routine +libpthread-routines += sysdep diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h new file mode 100644 index 000000000..c0b59c336 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h @@ -0,0 +1,221 @@ +/* Machine-specific pthread type layouts.  PowerPC version. +   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. + +   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.  */ + +#ifndef _BITS_PTHREADTYPES_H +#define _BITS_PTHREADTYPES_H	1 + +#include <bits/wordsize.h> + +#if __WORDSIZE == 64 +# define __SIZEOF_PTHREAD_ATTR_T 56 +# define __SIZEOF_PTHREAD_MUTEX_T 40 +# define __SIZEOF_PTHREAD_MUTEXATTR_T 4 +# define __SIZEOF_PTHREAD_COND_T 48 +# define __SIZEOF_PTHREAD_CONDATTR_T 4 +# define __SIZEOF_PTHREAD_RWLOCK_T 56 +# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8 +# define __SIZEOF_PTHREAD_BARRIER_T 32 +# define __SIZEOF_PTHREAD_BARRIERATTR_T 4 +#else +# define __SIZEOF_PTHREAD_ATTR_T 36 +# define __SIZEOF_PTHREAD_MUTEX_T 24 +# define __SIZEOF_PTHREAD_MUTEXATTR_T 4 +# define __SIZEOF_PTHREAD_COND_T 48 +# define __SIZEOF_PTHREAD_CONDATTR_T 4 +# define __SIZEOF_PTHREAD_RWLOCK_T 32 +# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8 +# define __SIZEOF_PTHREAD_BARRIER_T 20 +# define __SIZEOF_PTHREAD_BARRIERATTR_T 4 +#endif + + +/* Thread identifiers.  The structure of the attribute type is +   deliberately not exposed.  */ +typedef unsigned long int pthread_t; + + +typedef union +{ +  char __size[__SIZEOF_PTHREAD_ATTR_T]; +  long int __align; +} pthread_attr_t; + + +#if __WORDSIZE == 64 +typedef struct __pthread_internal_list +{ +  struct __pthread_internal_list *__prev; +  struct __pthread_internal_list *__next; +} __pthread_list_t; +#else +typedef struct __pthread_internal_slist +{ +  struct __pthread_internal_slist *__next; +} __pthread_slist_t; +#endif + + +/* Data structures for mutex handling.  The structure of the attribute +   type is deliberately not exposed.  */ +typedef union +{ +  struct __pthread_mutex_s +  { +    int __lock; +    unsigned int __count; +    int __owner; +#if __WORDSIZE == 64 +    unsigned int __nusers; +#endif +    /* KIND must stay at this position in the structure to maintain +       binary compatibility.  */ +    int __kind; +#if __WORDSIZE == 64 +    int __spins; +    __pthread_list_t __list; +# define __PTHREAD_MUTEX_HAVE_PREV	1 +#else +    unsigned int __nusers; +    __extension__ union +    { +      int __spins; +      __pthread_slist_t __list; +    }; +#endif +  } __data; +  char __size[__SIZEOF_PTHREAD_MUTEX_T]; +  long int __align; +} pthread_mutex_t; + +typedef union +{ +  char __size[__SIZEOF_PTHREAD_MUTEXATTR_T]; +  int __align; +} pthread_mutexattr_t; + + +/* Data structure for conditional variable handling.  The structure of +   the attribute type is deliberately not exposed.  */ +typedef union +{ +  struct +  { +    int __lock; +    unsigned int __futex; +    __extension__ unsigned long long int __total_seq; +    __extension__ unsigned long long int __wakeup_seq; +    __extension__ unsigned long long int __woken_seq; +    void *__mutex; +    unsigned int __nwaiters; +    unsigned int __broadcast_seq; +  } __data; +  char __size[__SIZEOF_PTHREAD_COND_T]; +  __extension__ long long int __align; +} pthread_cond_t; + +typedef union +{ +  char __size[__SIZEOF_PTHREAD_CONDATTR_T]; +  int __align; +} pthread_condattr_t; + + +/* Keys for thread-specific data */ +typedef unsigned int pthread_key_t; + + +/* Once-only execution */ +typedef int pthread_once_t; + + +#if defined __USE_UNIX98 || defined __USE_XOPEN2K +/* Data structure for read-write lock variable handling.  The +   structure of the attribute type is deliberately not exposed.  */ +typedef union +{ +# if __WORDSIZE == 64 +  struct +  { +    int __lock; +    unsigned int __nr_readers; +    unsigned int __readers_wakeup; +    unsigned int __writer_wakeup; +    unsigned int __nr_readers_queued; +    unsigned int __nr_writers_queued; +    int __writer; +    int __shared; +    unsigned long int __pad1; +    unsigned long int __pad2; +    /* FLAGS must stay at this position in the structure to maintain +       binary compatibility.  */ +    unsigned int __flags; +  } __data; +# else +  struct +  { +    int __lock; +    unsigned int __nr_readers; +    unsigned int __readers_wakeup; +    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 char __flags; +    int __writer; +  } __data; +# endif +  char __size[__SIZEOF_PTHREAD_RWLOCK_T]; +  long int __align; +} pthread_rwlock_t; + +typedef union +{ +  char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T]; +  long int __align; +} pthread_rwlockattr_t; +#endif + + +#ifdef __USE_XOPEN2K +/* POSIX spinlock data type.  */ +typedef volatile int pthread_spinlock_t; + + +/* POSIX barriers data type.  The structure of the type is +   deliberately not exposed.  */ +typedef union +{ +  char __size[__SIZEOF_PTHREAD_BARRIER_T]; +  long int __align; +} pthread_barrier_t; + +typedef union +{ +  char __size[__SIZEOF_PTHREAD_BARRIERATTR_T]; +  int __align; +} pthread_barrierattr_t; +#endif + + +#endif	/* bits/pthreadtypes.h */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h new file mode 100644 index 000000000..c7f121ba5 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h @@ -0,0 +1,41 @@ +/* Machine-specific POSIX semaphore type layouts.  PowerPC version. +   Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Paul Mackerras <paulus@au.ibm.com>, 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.  */ + +#ifndef _SEMAPHORE_H +# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead." +#endif + +#include <bits/wordsize.h> + +#if __WORDSIZE == 64 +# define __SIZEOF_SEM_T	32 +#else +# define __SIZEOF_SEM_T	16 +#endif + +/* Value returned if `sem_open' failed.  */ +#define SEM_FAILED      ((sem_t *) 0) + + +typedef union +{ +  char __size[__SIZEOF_SEM_T]; +  long int __align; +} sem_t; diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c new file mode 100644 index 000000000..e811ad74e --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c @@ -0,0 +1,25 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Paul Mackerras <paulus@au.ibm.com>. + +   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.  */ + +/* Value passed to 'clone' for initialization of the thread register.  */ +#define TLS_VALUE ((void *) (pd) \ +		   + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE) + +/* Get the real implementation.	 */ +#include <nptl/sysdeps/pthread/createthread.c> diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/fork.c new file mode 100644 index 000000000..06b7e1c69 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/fork.c @@ -0,0 +1 @@ +#include "../i386/fork.c" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h new file mode 100644 index 000000000..66c02cbbd --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h @@ -0,0 +1,314 @@ +/* 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. + +   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.  */ + +#ifndef _LOWLEVELLOCK_H +#define _LOWLEVELLOCK_H	1 + +#include <time.h> +#include <sys/param.h> +#include <bits/pthreadtypes.h> +#include <atomic.h> +#include <kernel-features.h> + +#ifndef __NR_futex +# define __NR_futex		221 +#endif +#define FUTEX_WAIT		0 +#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 + +#define lll_futex_wait(futexp, val, private) \ +  lll_futex_timed_wait (futexp, val, NULL, private) + +#define lll_futex_timed_wait(futexp, val, timespec, private) \ +  ({									      \ +    INTERNAL_SYSCALL_DECL (__err);					      \ +    long int __ret;							      \ +									      \ +    __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_wake(futexp, nr, private) \ +  ({									      \ +    INTERNAL_SYSCALL_DECL (__err);					      \ +    long int __ret;							      \ +									      \ +    __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_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, 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_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \ +  ({									      \ +    INTERNAL_SYSCALL_DECL (__err);					      \ +    long int __ret;							      \ +									      \ +    __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" +# 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 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" 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" (id), "m" (*futex)		      \ +		       : "cr0", "memory");				      \ +     __val;								      \ +  }) + +#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) __lll_robust_trylock (futex, 2) + +#define lll_cond_trylock(lock)	__lll_cond_trylock (&(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)					      \ +      {									      \ +	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_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, 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 *, int private) attribute_hidden; +extern int __lll_robust_timedlock_wait +  (int *futex, const struct timespec *, int private) attribute_hidden; + +#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, 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_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, private);				      \ +  })) + +#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, private);				      \ +  })) + +#define lll_islocked(futex) \ +  (futex != 0) + + +/* Initializers for lock.  */ +#define LLL_LOCK_INITIALIZER		(0) +#define LLL_LOCK_INITIALIZER_LOCKED	(1) + +/* The states of a lock are: +    0  -  untaken +    1  -  taken by one user +   >1  -  taken by more users */ + +/* 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 +   afterwards.	*/ +#define lll_wait_tid(tid) \ +  do {									      \ +    __typeof (tid) __tid;						      \ +    while ((__tid = (tid)) != 0)					      \ +      lll_futex_wait (&(tid), __tid, LLL_SHARED);			      \ +  } while (0) + +extern int __lll_timedwait_tid (int *, const struct timespec *) +     attribute_hidden; + +#define lll_timedwait_tid(tid, abstime) \ +  ({									      \ +    int __res = 0;							      \ +    if ((tid) != 0)							      \ +      __res = __lll_timedwait_tid (&(tid), (abstime));			      \ +    __res;								      \ +  }) + +#endif	/* lowlevellock.h */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/not-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/not-cancel.h new file mode 100644 index 000000000..acf1a617e --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/not-cancel.h @@ -0,0 +1 @@ +#include "../i386/not-cancel.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 new file mode 100644 index 000000000..675a997e9 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S @@ -0,0 +1,9 @@ +/* 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/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/pt-vfork.S new file mode 100644 index 000000000..61651fd97 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/pt-vfork.S @@ -0,0 +1,49 @@ +/* Copyright (C) 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2004. + +   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 <sysdep.h> +#define _ERRNO_H	1 +#include <bits/errno.h> +#include <bits/kernel-features.h> +#include <tcb-offsets.h> + +/* Clone the calling process, but without copying the whole address space. +   The calling process is suspended until the new process exits or is +   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process, +   and the process ID of the new process to the old process.  */ + +ENTRY (__vfork) +	lwz	0,PID(2) +	neg	0,0 +	stw	0,PID(2) + +	DO_CALL (SYS_ify (vfork)) + +	cmpwi	1,3,0 +	beqlr-	1 + +	lwz	0,PID(2) +	neg	0,0 +	stw	0,PID(2) + +	PSEUDO_RET + +PSEUDO_END (__vfork) + +weak_alias (__vfork, vfork) 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 new file mode 100644 index 000000000..88b24e7d9 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h @@ -0,0 +1,119 @@ +/* Cancellable system call stubs.  Linux/PowerPC version. +   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. + +   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., 51 Franklin Street, Fifth Floor, Boston MA +   02110-1301 USA.  */ + +#include <sysdep.h> +#include <tls.h> +#ifndef __ASSEMBLER__ +# include <nptl/pthreadP.h> +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args)				\ +  .section ".text";							\ +  ENTRY (name)								\ +    SINGLE_THREAD_P;							\ +    bne- .Lpseudo_cancel;						\ +  .type __##syscall_name##_nocancel,@function;				\ +  .globl __##syscall_name##_nocancel;					\ +  __##syscall_name##_nocancel:						\ +    DO_CALL (SYS_ify (syscall_name));					\ +    PSEUDO_RET;								\ +  .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;	\ +  .Lpseudo_cancel:							\ +    stwu 1,-48(1);							\ +    cfi_adjust_cfa_offset (48);						\ +    mflr 9;								\ +    stw 9,52(1);							\ +    cfi_offset (lr, 4);							\ +    DOCARGS_##args;	/* save syscall args around CENABLE.  */	\ +    CENABLE;								\ +    stw 3,16(1);	/* store CENABLE return value (MASK).  */	\ +    UNDOCARGS_##args;	/* restore syscall args.  */			\ +    DO_CALL (SYS_ify (syscall_name));					\ +    mfcr 0;		/* save CR/R3 around CDISABLE.  */		\ +    stw 3,8(1);								\ +    stw 0,12(1);							\ +    lwz 3,16(1);	/* pass MASK to CDISABLE.  */			\ +    CDISABLE;								\ +    lwz 4,52(1);							\ +    lwz 0,12(1);	/* restore CR/R3. */				\ +    lwz 3,8(1);								\ +    mtlr 4;								\ +    mtcr 0;								\ +    addi 1,1,48; + +# define DOCARGS_0 +# define UNDOCARGS_0 + +# define DOCARGS_1	stw 3,20(1); DOCARGS_0 +# define UNDOCARGS_1	lwz 3,20(1); UNDOCARGS_0 + +# define DOCARGS_2	stw 4,24(1); DOCARGS_1 +# define UNDOCARGS_2	lwz 4,24(1); UNDOCARGS_1 + +# define DOCARGS_3	stw 5,28(1); DOCARGS_2 +# define UNDOCARGS_3	lwz 5,28(1); UNDOCARGS_2 + +# define DOCARGS_4	stw 6,32(1); DOCARGS_3 +# define UNDOCARGS_4	lwz 6,32(1); UNDOCARGS_3 + +# define DOCARGS_5	stw 7,36(1); DOCARGS_4 +# define UNDOCARGS_5	lwz 7,36(1); UNDOCARGS_4 + +# define DOCARGS_6	stw 8,40(1); DOCARGS_5 +# define UNDOCARGS_6	lwz 8,40(1); UNDOCARGS_5 + +# ifdef IS_IN_libpthread +#  define CENABLE	bl __pthread_enable_asynccancel@local +#  define CDISABLE	bl __pthread_disable_asynccancel@local +# elif !defined NOT_IN_libc +#  define CENABLE	bl __libc_enable_asynccancel@local +#  define CDISABLE	bl __libc_disable_asynccancel@local +# elif defined IS_IN_librt +#  define CENABLE	bl __librt_enable_asynccancel@local +#  define CDISABLE	bl __librt_disable_asynccancel@local +# else +#  error Unsupported library +# endif + +# ifndef __ASSEMBLER__ +#  define SINGLE_THREAD_P						\ +  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				\ +				   header.multiple_threads) == 0, 1) +# else +#  define SINGLE_THREAD_P						\ +  lwz 10,MULTIPLE_THREADS_OFFSET(2);					\ +  cmpwi 10,0 +# endif + +#elif !defined __ASSEMBLER__ + +# define SINGLE_THREAD_P (1) +# 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 new file mode 100644 index 000000000..eed2a8f1a --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S @@ -0,0 +1,57 @@ +/* Copyright (C) 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2004. + +   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 <sysdep.h> +#define _ERRNO_H	1 +#include <bits/errno.h> +#include <bits/kernel-features.h> +#include <tcb-offsets.h> + +/* Clone the calling process, but without copying the whole address space. +   The calling process is suspended until the new process exits or is +   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process, +   and the process ID of the new process to the old process.  */ + +ENTRY (__vfork) +	lwz	0,PID(2) +	cmpwi	0,0,0 +	neg	0,0 +	bne-	0,1f +	lis	0,0x8000 +1:	stw	0,PID(2) + +	DO_CALL (SYS_ify (vfork)) + +	cmpwi	1,3,0 +	beqlr-	1 + +	lwz	0,PID(2) +	/* Cannot use clrlwi. here, because cr0 needs to be preserved +	   until PSEUDO_RET.  */ +	clrlwi	4,0,1 +	cmpwi	1,4,0 +	beq-	1,1f +	neg	4,0 +1:	stw	4,PID(2) + +	PSEUDO_RET + +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) +weak_alias (__vfork, vfork) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S new file mode 100644 index 000000000..675a997e9 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S @@ -0,0 +1,9 @@ +/* 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/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/pt-vfork.S new file mode 100644 index 000000000..e5b7b535c --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/pt-vfork.S @@ -0,0 +1,49 @@ +/* Copyright (C) 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2004. + +   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 <sysdep.h> +#define _ERRNO_H	1 +#include <bits/errno.h> +#include <bits/kernel-features.h> +#include <tcb-offsets.h> + +/* Clone the calling process, but without copying the whole address space. +   The calling process is suspended until the new process exits or is +   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process, +   and the process ID of the new process to the old process.  */ + +ENTRY (__vfork) +	lwz	0,PID(13) +	neg	0,0 +	stw	0,PID(13) + +	DO_CALL (SYS_ify (vfork)) + +	cmpwi	1,3,0 +	beqlr-	1 + +	lwz	0,PID(13) +	neg	0,0 +	stw	0,PID(13) + +	PSEUDO_RET + +PSEUDO_END (__vfork) + +weak_alias (__vfork, vfork) 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 new file mode 100644 index 000000000..707765ab5 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h @@ -0,0 +1,125 @@ +/* Cancellable system call stubs.  Linux/PowerPC64 version. +   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. + +   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., 51 Franklin Street, Fifth Floor, Boston MA +   02110-1301 USA.  */ + +#include <sysdep.h> +#include <tls.h> +#ifndef __ASSEMBLER__ +# include <nptl/pthreadP.h> +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt + +# ifdef HAVE_ASM_GLOBAL_DOT_NAME +#  define DASHDASHPFX(str) .__##str +# else +#  define DASHDASHPFX(str) __##str +# endif + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args)				\ +  .section ".text";							\ +  ENTRY (name)								\ +    SINGLE_THREAD_P;							\ +    bne- .Lpseudo_cancel;						\ +  .type DASHDASHPFX(syscall_name##_nocancel),@function;			\ +  .globl DASHDASHPFX(syscall_name##_nocancel);				\ +  DASHDASHPFX(syscall_name##_nocancel):					\ +    DO_CALL (SYS_ify (syscall_name));					\ +    PSEUDO_RET;								\ +  .size DASHDASHPFX(syscall_name##_nocancel),.-DASHDASHPFX(syscall_name##_nocancel);	\ +  .Lpseudo_cancel:							\ +    stdu 1,-128(1);							\ +    cfi_adjust_cfa_offset (128);					\ +    mflr 9;								\ +    std  9,128+16(1);							\ +    cfi_offset (lr, 16);						\ +    DOCARGS_##args;	/* save syscall args around CENABLE.  */	\ +    CENABLE;								\ +    std  3,72(1);	/* store CENABLE return value (MASK).  */	\ +    UNDOCARGS_##args;	/* restore syscall args.  */			\ +    DO_CALL (SYS_ify (syscall_name));					\ +    mfcr 0;		/* save CR/R3 around CDISABLE.  */		\ +    std  3,64(1);							\ +    std  0,8(1);							\ +    ld   3,72(1);	/* pass MASK to CDISABLE.  */			\ +    CDISABLE;								\ +    ld   9,128+16(1);							\ +    ld   0,8(1);	/* restore CR/R3. */				\ +    ld   3,64(1);							\ +    mtlr 9;								\ +    mtcr 0;								\ +    addi 1,1,128; + +# define DOCARGS_0 +# define UNDOCARGS_0 + +# define DOCARGS_1	std 3,80(1); DOCARGS_0 +# define UNDOCARGS_1	ld 3,80(1); UNDOCARGS_0 + +# define DOCARGS_2	std 4,88(1); DOCARGS_1 +# define UNDOCARGS_2	ld 4,88(1); UNDOCARGS_1 + +# define DOCARGS_3	std 5,96(1); DOCARGS_2 +# define UNDOCARGS_3	ld 5,96(1); UNDOCARGS_2 + +# define DOCARGS_4	std 6,104(1); DOCARGS_3 +# define UNDOCARGS_4	ld 6,104(1); UNDOCARGS_3 + +# define DOCARGS_5	std 7,112(1); DOCARGS_4 +# define UNDOCARGS_5	ld 7,112(1); UNDOCARGS_4 + +# define DOCARGS_6	std 8,120(1); DOCARGS_5 +# define UNDOCARGS_6	ld 8,120(1); UNDOCARGS_5 + +# ifdef IS_IN_libpthread +#  define CENABLE	bl JUMPTARGET(__pthread_enable_asynccancel) +#  define CDISABLE	bl JUMPTARGET(__pthread_disable_asynccancel) +# elif !defined NOT_IN_libc +#  define CENABLE	bl JUMPTARGET(__libc_enable_asynccancel) +#  define CDISABLE	bl JUMPTARGET(__libc_disable_asynccancel) +# elif defined IS_IN_librt +#  define CENABLE	bl JUMPTARGET(__librt_enable_asynccancel) +#  define CDISABLE	bl JUMPTARGET(__librt_disable_asynccancel) +# else +#  error Unsupported library +# endif + +# ifndef __ASSEMBLER__ +#  define SINGLE_THREAD_P						\ +  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				\ +				   header.multiple_threads) == 0, 1) +# else +#   define SINGLE_THREAD_P						\ +  lwz   10,MULTIPLE_THREADS_OFFSET(13);				\ +  cmpwi 10,0 +# endif + +#elif !defined __ASSEMBLER__ + +# define SINGLE_THREAD_P (1) +# 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/timer_create.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_create.c new file mode 100644 index 000000000..172223af3 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_create.c @@ -0,0 +1 @@ +#include "../x86_64/timer_create.c" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_delete.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_delete.c new file mode 100644 index 000000000..537516e0a --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_delete.c @@ -0,0 +1 @@ +#include "../x86_64/timer_delete.c" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_getoverr.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_getoverr.c new file mode 100644 index 000000000..3f21a73c9 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_getoverr.c @@ -0,0 +1 @@ +#include "../x86_64/timer_getoverr.c" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_gettime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_gettime.c new file mode 100644 index 000000000..a50143adc --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_gettime.c @@ -0,0 +1 @@ +#include "../x86_64/timer_gettime.c" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_settime.c new file mode 100644 index 000000000..37baeffac --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_settime.c @@ -0,0 +1 @@ +#include "../x86_64/timer_settime.c" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S new file mode 100644 index 000000000..26885bb95 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S @@ -0,0 +1,55 @@ +/* Copyright (C) 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2004. + +   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 <sysdep.h> +#define _ERRNO_H	1 +#include <bits/errno.h> +#include <bits/kernel-features.h> +#include <tcb-offsets.h> + +/* Clone the calling process, but without copying the whole address space. +   The calling process is suspended until the new process exits or is +   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process, +   and the process ID of the new process to the old process.  */ + +ENTRY (__vfork) +	lwz	0,PID(13) +	cmpwi	0,0,0 +	neg	0,0 +	bne-	0,1f +	lis	0,0x8000 +1:	stw	0,PID(13) + +	DO_CALL (SYS_ify (vfork)) + +	cmpwi	1,3,0 +	beqlr-	1 + +	lwz	0,PID(13) +	clrlwi	4,0,1 +	cmpwi	1,4,0 +	beq-	1,1f +	neg	4,0 +1:	stw	4,PID(13) + +	PSEUDO_RET + +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) +weak_alias (__vfork, vfork) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c new file mode 100644 index 000000000..b6d6b3d55 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <setjmp.h> +#include <stdlib.h> +#include <bits/wordsize.h> +#include "pthreadP.h" + +void +__vmx_longjmp (jmp_buf env, int val) +{ +  __libc_longjmp (env, val); +} + +void +__vmx_siglongjmp (jmp_buf env, int val) +{ +  __libc_siglongjmp (env, val); +} +weak_alias(__vmx_longjmp, longjmp) +weak_alias(__vmx_siglongjmp, siglongjmp) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c new file mode 100644 index 000000000..969078094 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c @@ -0,0 +1,100 @@ +/* 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. + +   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> + + +unsigned long int __fork_generation attribute_hidden; + + +static void +clear_once_control (void *arg) +{ +  pthread_once_t *once_control = (pthread_once_t *) arg; + +  *once_control = 0; +  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE); +} + + +int +__pthread_once (pthread_once_t *once_control, void (*init_routine) (void)) +{ +  for (;;) +    { +      int oldval; +      int newval; +      int tmp; + +      /* Pseudo code: +	 newval = __fork_generation | 1; +	 oldval = *once_control; +	 if ((oldval & 2) == 0) +	   *once_control = newval; +	 Do this atomically. +      */ +      newval = __fork_generation | 1; +      __asm __volatile ("1:	lwarx	%0,0,%3\n" +			"	andi.	%1,%0,2\n" +			"	bne	2f\n" +			"	stwcx.	%4,0,%3\n" +			"	bne	1b\n" +			"2:	isync" +			: "=&r" (oldval), "=&r" (tmp), "=m" (*once_control) +			: "r" (once_control), "r" (newval), "m" (*once_control) +			: "cr0"); + +      /* Check if the initializer has already been done.  */ +      if ((oldval & 2) != 0) +	return 0; + +      /* Check if another thread already runs the initializer.	*/ +      if ((oldval & 1) == 0) +	break; + +      /* Check whether the initializer execution was interrupted by a fork.  */ +      if (oldval != newval) +	break; + +      /* Same generation, some other thread was faster. Wait.  */ +      lll_futex_wait (once_control, oldval, LLL_PRIVATE); +    } + + +  /* This thread is the first here.  Do the initialization. +     Register a cleanup handler so that in case the thread gets +     interrupted the initialization can be restarted.  */ +  pthread_cleanup_push (clear_once_control, once_control); + +  init_routine (); + +  pthread_cleanup_pop (0); + + +  /* Add one to *once_control to take the bottom 2 bits from 01 to 10.  */ +  atomic_increment (once_control); + +  /* Wake up all other threads.  */ +  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE); + +  return 0; +} +weak_alias (__pthread_once, pthread_once) +strong_alias (__pthread_once, __pthread_once_internal) 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 new file mode 100644 index 000000000..0082c570a --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c @@ -0,0 +1,47 @@ +/* sem_post -- post to a POSIX semaphore.  Powerpc version. +   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. + +   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 <errno.h> +#include <sysdep.h> +#include <lowlevellock.h> +#include <internaltypes.h> +#include <semaphore.h> + +int +__new_sem_post (sem_t *sem) +{ +  struct new_sem *isem = (struct new_sem *) sem; + +  __asm __volatile (__lll_rel_instr ::: "memory"); +  atomic_increment (&isem->value); +  __asm __volatile (__lll_acq_instr ::: "memory"); +  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) | 
