From: Carlos O'Donell Date: Sat, 28 Jul 2007 21:26:44 +0000 (+0000) Subject: 2007-07-28 Carlos O'Donell X-Git-Tag: upstream/2.30~10627^2~754 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b599860dc82a3a3eb2744d6ba4917ef2a2f5ba47;p=external%2Fglibc.git 2007-07-28 Carlos O'Donell * sysdeps/unix/sysv/linux/hppa/nptl/internaltypes.h: Remove. * sysdeps/unix/sysv/linux/hppa/nptl/bits/pthreadtypes.h (pthread_rwlock_t): Split __flags into __pad2, __pad1, __shared, and __flags. Update comments. Update copyright. * sysdeps/hppa/nptl/tls.h: Define THREAD_GSCOPE_FLAG_UNUSED, THREAD_GSCOPE_FLAG_USED, THREAD_GSOPE_FLAG_WAIT, THREAD_GSCOPE_RSEET_FLAG, THREAD_GSCOPE_SET_FLAG, THREAD_GSCOPE_WAIT. Update copyright. * sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.c: Update copyright. (__lll_lock_wait): Call lll_futex_wait with LLL_SHARED. (__lll_timedlock_wait): Call lll_futex_timed_wait with LLL_SHARED. (lll_unlock_Wake_cb): Use lll_private_futex_wake. (___lll_timedwait_tid): Call lll_futex_timed_wait with LLL_SAHRED. * sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h: Define FUTEX_PRIVATE_FLAG, LLL_PRIVATE, LLL_SHARED, lll_private_futex_wait, lll_private_futex_timed_wait, lll_private_Futex_wake. Add private argument to lll_futex_wait, lll_futex_timed_wait, lll_futex_wake, lll_futex_wake_unlock. * sysdeps/unix/sysv/linux/hppa/nptl/pthread_once.c: Update copyright. (clear_once_control): Use lll_private_futex_wake. (__pthread_once): Use lll_private_futex_wait, and lll_private_futex_wake. 2007-07-28 Randolph Chung * sysdeps/hppa/nptl/tls.h (DB_THREAD_SELF): Fix definition. --- diff --git a/ChangeLog.hppa b/ChangeLog.hppa index 967dadf..ff0a7a4 100644 --- a/ChangeLog.hppa +++ b/ChangeLog.hppa @@ -1,4 +1,33 @@ -2006-07-16 Jeff Bailey +2007-07-28 Carlos O'Donell + + * sysdeps/unix/sysv/linux/hppa/nptl/internaltypes.h: Remove. + * sysdeps/unix/sysv/linux/hppa/nptl/bits/pthreadtypes.h + (pthread_rwlock_t): Split __flags into __pad2, __pad1, __shared, + and __flags. Update comments. Update copyright. + * sysdeps/hppa/nptl/tls.h: Define THREAD_GSCOPE_FLAG_UNUSED, + THREAD_GSCOPE_FLAG_USED, THREAD_GSOPE_FLAG_WAIT, + THREAD_GSCOPE_RSEET_FLAG, THREAD_GSCOPE_SET_FLAG, THREAD_GSCOPE_WAIT. + Update copyright. + * sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.c: Update copyright. + (__lll_lock_wait): Call lll_futex_wait with LLL_SHARED. + (__lll_timedlock_wait): Call lll_futex_timed_wait with LLL_SHARED. + (lll_unlock_Wake_cb): Use lll_private_futex_wake. + (___lll_timedwait_tid): Call lll_futex_timed_wait with LLL_SAHRED. + * sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h: Define + FUTEX_PRIVATE_FLAG, LLL_PRIVATE, LLL_SHARED, lll_private_futex_wait, + lll_private_futex_timed_wait, lll_private_Futex_wake. Add private + argument to lll_futex_wait, lll_futex_timed_wait, lll_futex_wake, + lll_futex_wake_unlock. + * sysdeps/unix/sysv/linux/hppa/nptl/pthread_once.c: Update copyright. + (clear_once_control): Use lll_private_futex_wake. + (__pthread_once): Use lll_private_futex_wait, and + lll_private_futex_wake. + +2007-07-28 Randolph Chung + + * sysdeps/hppa/nptl/tls.h (DB_THREAD_SELF): Fix definition. + +2007-06-16 Jeff Bailey * sysdeps/unix/sysv/linux/hppa/sys/procfs.h: Don't include asm/elf.h. Declare elf_greg_t, elf_gregset_t, diff --git a/sysdeps/hppa/nptl/tls.h b/sysdeps/hppa/nptl/tls.h index 0759aec..d2d725e 100644 --- a/sysdeps/hppa/nptl/tls.h +++ b/sysdeps/hppa/nptl/tls.h @@ -1,5 +1,5 @@ /* Definition for thread-local data handling. NPTL/hppa version. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 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 @@ -117,11 +117,12 @@ typedef struct __self - 1; \ }) -/* FIXME */ -/* Magic for libthread_db to know how to do THREAD_SELF. */ +/* Magic for libthread_db to know how to do THREAD_SELF. + Our thread pointer is stored in cr27. See asm/elf.h for the offset into + elf_gregset_t. The thread descriptor is sizeof (struct pthread) away. */ # define DB_THREAD_SELF \ - REGISTER (32, 32, 32 * 4, -sizeof (struct pthread)) - + REGISTER (32, 32, 53 * 4, -sizeof (struct pthread)) + /* Access to data in the thread descriptor is easy. */ # define THREAD_GETMEM(descr, member) \ descr->member @@ -146,6 +147,29 @@ static inline void __set_cr27(struct pthread *cr27) : : "r" (cr27) : "r26" ); } +/* Get and set the global scope generation counter in struct pthread. */ +#define THREAD_GSCOPE_FLAG_UNUSED 0 +#define THREAD_GSCOPE_FLAG_USED 1 +#define THREAD_GSCOPE_FLAG_WAIT 2 +#define THREAD_GSCOPE_RESET_FLAG() \ + do \ + { int __res \ + = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \ + THREAD_GSCOPE_FLAG_UNUSED); \ + if (__res == THREAD_GSCOPE_FLAG_WAIT) \ + lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \ + } \ + while (0) +#define THREAD_GSCOPE_SET_FLAG() \ + do \ + { \ + THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \ + atomic_write_barrier (); \ + } \ + while (0) +#define THREAD_GSCOPE_WAIT() \ + GL(dl_wait_lookup_done) () + #endif /* __ASSEMBLER__ */ #endif /* tls.h */ diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/bits/pthreadtypes.h b/sysdeps/unix/sysv/linux/hppa/nptl/bits/pthreadtypes.h index e1c5325..62fc80c 100644 --- a/sysdeps/unix/sysv/linux/hppa/nptl/bits/pthreadtypes.h +++ b/sysdeps/unix/sysv/linux/hppa/nptl/bits/pthreadtypes.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2005, 2006, 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 @@ -19,13 +19,14 @@ #ifndef _BITS_PTHREADTYPES_H #define _BITS_PTHREADTYPES_H 1 -/* Linuxthread type sizes: +/* Linuxthread type sizes (bytes): sizeof(pthread_attr_t) = 0x24 (36) sizeof(pthread_mutex_t) = 0x30 (48) sizeof(pthread_mutexattr_t) = 0x4 (4) sizeof(pthread_cond_t) = 0x30 (48) - = Grew to 64 bytes in NPTL. - No pthread_cond_compat_t ... + = Expanded to 64 bytes in NPTL. + sizeof(pthread_cond_compat_t) = 0xc (12) + = Did not exist in Linuxthreads. sizeof(pthread_condattr_t) = 0x4 (4) sizeof(pthread_rwlock_t) = 0x40 (64) sizeof(pthread_rwlockattr_t) = 0x8 (8) @@ -52,9 +53,9 @@ typedef unsigned long int pthread_t; implementation. For NPTL we use LWS Compare and Exchange to implement primitives. */ #if 0 -typedef struct { +typedef volatile struct { int lock[4]; -} __atomic_lock_t; +} __attribute__ ((aligned(16))) __atomic_lock_t; #endif typedef union @@ -149,7 +150,10 @@ typedef union unsigned int __nr_writers_queued; /* FLAGS must stay at this position in the structure to maintain binary compatibility. */ - unsigned int __flags; + unsigned char __pad2; + unsigned char __pad1; + unsigned char __shared; + unsigned char __flags; int __writer; } __data; char __size[__SIZEOF_PTHREAD_RWLOCK_T]; diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/internaltypes.h b/sysdeps/unix/sysv/linux/hppa/nptl/internaltypes.h deleted file mode 100644 index 528c2a7..0000000 --- a/sysdeps/unix/sysv/linux/hppa/nptl/internaltypes.h +++ /dev/null @@ -1,153 +0,0 @@ -/* Copyright (C) 2002, 2003, 2004 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. */ - -#ifndef _INTERNALTYPES_H -#define _INTERNALTYPES_H 1 - -#include - - -struct pthread_attr -{ - /* Scheduler parameters and priority. */ - struct sched_param schedparam; - int schedpolicy; - /* Various flags like detachstate, scope, etc. */ - int flags; - /* Size of guard area. */ - size_t guardsize; - /* Stack handling. */ - void *stackaddr; - size_t stacksize; - /* Affinity map. */ - cpu_set_t *cpuset; - size_t cpusetsize; -}; - -#define ATTR_FLAG_DETACHSTATE 0x0001 -#define ATTR_FLAG_NOTINHERITSCHED 0x0002 -#define ATTR_FLAG_SCOPEPROCESS 0x0004 -#define ATTR_FLAG_STACKADDR 0x0008 -#define ATTR_FLAG_OLDATTR 0x0010 -#define ATTR_FLAG_SCHED_SET 0x0020 -#define ATTR_FLAG_POLICY_SET 0x0040 - - -/* Mutex attribute data structure. */ -struct pthread_mutexattr -{ - /* Identifier for the kind of mutex. - - Bit 31 is set if the mutex is to be shared between processes. - - Bit 0 to 30 contain one of the PTHREAD_MUTEX_ values to identify - the type of the mutex. */ - int mutexkind; -}; - - -/* Conditional variable attribute data structure. */ -struct pthread_condattr -{ - /* Combination of values: - - Bit 0 : flag whether coditional variable will be shareable between - processes. - - Bit 1-7: clock ID. */ - int value; -}; - - -/* The __NWAITERS field is used as a counter and to house the number - of bits which represent the clock. COND_CLOCK_BITS is the number - of bits reserved for the clock. */ -#define COND_CLOCK_BITS 1 - - -/* Read-write lock variable attribute data structure. */ -struct pthread_rwlockattr -{ - int lockkind; - int pshared; -}; - - -/* Barrier data structure. */ -struct pthread_barrier -{ - unsigned int curr_event; - int lock; - unsigned int left; - unsigned int init_count; -}; - - -/* Barrier variable attribute data structure. */ -struct pthread_barrierattr -{ - int pshared; -}; - - -/* Thread-local data handling. */ -struct pthread_key_struct -{ - /* Sequence numbers. Even numbers indicated vacant entries. Note - that zero is even. We use uintptr_t to not require padding on - 32- and 64-bit machines. On 64-bit machines it helps to avoid - wrapping, too. */ - uintptr_t seq; - - /* Destructor for the data. */ - void (*destr) (void *); -}; - -/* Check whether an entry is unused. */ -#define KEY_UNUSED(p) (((p) & 1) == 0) -/* Check whether a key is usable. We cannot reuse an allocated key if - the sequence counter would overflow after the next destroy call. - This would mean that we potentially free memory for a key with the - same sequence. This is *very* unlikely to happen, A program would - have to create and destroy a key 2^31 times (on 32-bit platforms, - on 64-bit platforms that would be 2^63). If it should happen we - simply don't use this specific key anymore. */ -#define KEY_USABLE(p) (((uintptr_t) (p)) < ((uintptr_t) ((p) + 2))) - - -/* Handling of read-write lock data. */ -// XXX For now there is only one flag. Maybe more in future. -#define RWLOCK_RECURSIVE(rwlock) ((rwlock)->__data.__flags != 0) - - -/* Semaphore variable structure. */ -struct sem -{ - unsigned int count; -}; - - -/* Compatibility type for old conditional variable interfaces. */ -typedef struct -{ - pthread_cond_t *cond; -} pthread_cond_2_0_t; - -#endif /* internaltypes.h */ - diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.c b/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.c index d2919ee..236d29c 100644 --- a/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.c +++ b/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.c @@ -1,5 +1,5 @@ /* low level locking for pthread library. Generic futex-using version. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Paul Mackerras , 2003. @@ -31,7 +31,7 @@ __lll_lock_wait (lll_lock_t *futex) { int oldval = atomic_compare_and_exchange_val_acq (futex, 2, 1); if (oldval != 0) - lll_futex_wait (futex, 2); + lll_futex_wait (futex, 2, LLL_SHARED); } while (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0); } @@ -68,7 +68,7 @@ __lll_timedlock_wait (lll_lock_t *futex, const struct timespec *abstime) /* Wait. */ int oldval = atomic_compare_and_exchange_val_acq (futex, 2, 1); if (oldval != 0) - lll_futex_timed_wait (futex, 2, &rt); + lll_futex_timed_wait (futex, 2, &rt, LLL_SHARED); } while (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0); return 0; @@ -83,7 +83,7 @@ lll_unlock_wake_cb (lll_lock_t *futex) int val = atomic_exchange_rel (futex, 0); if (__builtin_expect (val > 1, 0)) - lll_futex_wake (futex, 1); + lll_private_futex_wake (futex, 1); return 0; } @@ -119,7 +119,7 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime) return ETIMEDOUT; /* Wait until thread terminates. */ - 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/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h b/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h index 3b2b0f1..f8a9555 100644 --- a/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h +++ b/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2005, 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 @@ -39,6 +39,13 @@ #define FUTEX_LOCK_PI 6 #define FUTEX_UNLOCK_PI 7 #define FUTEX_TRYLOCK_PI 8 +#define FUTEX_PRIVATE_FLAG 128 + +/* Values for 'private' parameter of locking macros. Yes, the + definition seems to be backwards. But it is not. The bit will be + reversed before passing to the system call. */ +#define LLL_PRIVATE 0 +#define LLL_SHARED FUTEX_PRIVATE_FLAG /* Initialize locks to zero. */ #define LLL_MUTEX_LOCK_INITIALIZER (0) @@ -48,39 +55,82 @@ typedef int lll_lock_t; -#define lll_futex_wait(futexp, val) \ +#define lll_futex_wait(futexp, val, private) \ + lll_futex_timed_wait (futexp, val, 0, private) + +#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); \ + (futexp), FUTEX_WAIT, (val), (timespec)); \ __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)); \ + (futexp), FUTEX_WAKE, (nr), 0); \ __ret; \ }) -#define lll_futex_wake(futexp, nr) \ +#define lll_private_futex_wait(futex, val) \ + lll_private_futex_timed_wait (futex, val, NULL) + +#ifdef __ASSUME_PRIVATE_FUTEX +# define lll_private_futex_timed_wait(futex, val, timeout) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ __ret = INTERNAL_SYSCALL (futex, __err, 4, \ - (futexp), FUTEX_WAKE, (nr), 0); \ + (futexp), FUTEX_WAIT | FUTEX_PRIVATE_FLAG, \ + (val), (timespec)); \ __ret; \ }) +# define lll_private_futex_wake(futexp, nr) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, \ + (futexp), FUTEX_WAKE | FUTEX_PRIVATE_FLAG, \ + (nr), 0); \ + __ret; \ + }) + +#else + +# define lll_private_futex_timed_wait(futexp, val, timespec) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret, __op; \ + __op = FUTEX_WAIT | THREAD_GETMEM (THREAD_SELF, header.private_futex); \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, \ + (futexp), __op, (val), (timespec)); \ + __ret; \ + }) + +# define lll_private_futex_wake(futexp, nr) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret, __op; \ + __op = FUTEX_WAKE | THREAD_GETMEM (THREAD_SELF, header.private_futex); \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, \ + (futexp), __op, (nr), 0); \ + __ret; \ + }) +#endif + + + #define lll_robust_mutex_dead(futexv) \ do \ { \ int *__futexp = &(futexv); \ atomic_or (__futexp, FUTEX_OWNER_DIED); \ - lll_futex_wake (__futexp, 1); \ + lll_futex_wake (__futexp, 1, 0); \ } \ while (0) @@ -96,7 +146,7 @@ typedef int lll_lock_t; }) /* Returns non-zero if error happened, zero if success. */ -#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) \ +#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ @@ -201,7 +251,7 @@ __lll_mutex_unlock (lll_lock_t *futex) { int val = atomic_exchange_rel (futex, 0); if (__builtin_expect (val > 1, 0)) - lll_futex_wake (futex, 1); + lll_futex_wake (futex, 1, 0); } #define lll_mutex_unlock(futex) __lll_mutex_unlock(&(futex)) @@ -211,7 +261,7 @@ __lll_robust_mutex_unlock (int *futex, int mask) { int val = atomic_exchange_rel (futex, 0); if (__builtin_expect (val & mask, 0)) - lll_futex_wake (futex, 1); + lll_futex_wake (futex, 1, 0); } #define lll_robust_mutex_unlock(futex) \ __lll_robust_mutex_unlock(&(futex), FUTEX_WAITERS) @@ -221,7 +271,7 @@ static inline void __attribute__ ((always_inline)) __lll_mutex_unlock_force (lll_lock_t *futex) { (void) atomic_exchange_rel (futex, 0); - lll_futex_wake (futex, 1); + lll_futex_wake (futex, 1, 0); } #define lll_mutex_unlock_force(futex) __lll_mutex_unlock_force(&(futex)) @@ -256,10 +306,10 @@ extern int lll_unlock_wake_cb (lll_lock_t *__futex) attribute_hidden; 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); \ + do { \ + __typeof (tid) __tid; \ + while ((__tid = (tid)) != 0) \ + lll_futex_wait (&(tid), __tid, 0); \ } while (0) extern int __lll_timedwait_tid (int *, const struct timespec *) diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/hppa/nptl/pthread_once.c index 649b752..b89e40c 100644 --- a/sysdeps/unix/sysv/linux/hppa/nptl/pthread_once.c +++ b/sysdeps/unix/sysv/linux/hppa/nptl/pthread_once.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2005, 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_private_futex_wake (once_control, INT_MAX); } @@ -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_private_futex_wait (once_control, newval); 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_private_futex_wake (once_control, INT_MAX); break; }