Update HPPA LinuxThread implementation and remove old .dpatch's
PATCH 1/1 Update HPPA LinuxThread implementation and remove old .dpatch's
debian-glibc,
With regards to GNU/Libc 2.3.x
The following is an update of LinuxThreads for HPPA, the changelog is in progress and it has shown no regressions from a testing standpoint. It actually does better in the gcc/g++ testsuite. This work represents some long discussions between John David Anglin and myself, please read the dpatch for more information about a specific patch.
Please remove the following .dpatch files from debian-glibc's CVS:
glibc23-02-hppa-min-kern-unwind-fde.dpatch
glibc23-03-hppa-mcontext.dpatch
glibc23-04-hppa-fcntl64.dpatch
glibc23-05-hppa-buildhack.dpatch
glibc23-06-hppa-tests.dpatch
glibc23-08-hppa-configure.dpatch
They are no longer being used and were superceeded by CVS patches.
Please replace glibc23-00-hppa-pthreads.dpatch with the attached version. Please add glibc23-hppa-malloc-align.dpatch to the list of HPPA patches.
Quick Summary:
- LinuxThreads is now using a self-aligning lock.
- Malloc alignment has been moved back to 8 for optimal performance.
I did this work over 2-3 weeks ago, but due to current time constraints it was behind "libgcc-compat hppa" on the queue, and thus didn't get out. Randolph Chung recently fixed hppa's __clz_tab libgcc-compat issue, which means I can take the 5 minutes I need to send this email :)
This code has been heavily tested by John and myself, though should any HPPA users find problems, or have comments, please file bugs and/or contact me direclty or via any of the lists :)
Happy hacking.
Cheers,
Carlos.
#! /bin/sh -e
# DP: Description: HP/PARISC Linuxthreads impelementation "__ldcw_align()" # DP: Author: Carlos O'Donell <[email protected]>
# DP: Upstream status: Not submitted
# DP: Status Details: Writing changelogs.
# DP: Date: March 1st, 2003
# This patch represents some of the work that John David Anglin and myself
# have done to try get Linuxthreads passing all the gcc/g++/glibc testsuites. # The biggest issue we are trying to solve is that of the required 16-byte # alignment for all locks. Since gcc cannot provide this type of alignment # in all scenarios, John devised an interesting self-alinging solution. # The implementation of that solution is presented here. # - Carlos.
if [ $# -ne 2 ]; then
echo >&2 "basename $0: script expects -patch|-unpatch as argument" exit 1
fi
case "$1" in
-patch) patch -d "$2" -f --no-backup-if-mismatch -p1 < $0;;
-unpatch) patch -d "$2" -f --no-backup-if-mismatch -R -p1 < $0;;
*)
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1esac
exit 0
# append the patch here and adjust the -p? flag in the patch calls.
diff -urN glibc-2.3.1.orig/linuxthreads/descr.h glibc-2.3.1/linuxthreads/descr.h
--- glibc-2.3.1.orig/linuxthreads/descr.h 2003-01-15 12:58:11.000000000 -0500
+++ glibc-2.3.1/linuxthreads/descr.h 2003-01-15 18:24:36.000000000 -0500
@@ -70,7 +70,7 @@
/* Atomic counter made possible by compare_and_swap */
struct pthread_atomic {
long p_count;
- int p_spinlock;
+ __atomic_lock_t p_spinlock;
};linuxthreads/pt-machine.c +3 -1
@@ -19,7 +19,9 @@#define PT_EI -extern long int testandset (int *spinlock); +#include <pthread.h> + +extern long int testandset (__atomic_lock_t *spinlock);extern int __compare_and_swap (long int *p,long int oldval,long int newval);#include <pt-machine.h>
linuxthreads/pthread.c +7 -7
@@ -296,9 +296,9 @@pthread_descr self;/* First of all init __pthread_handles[0] and [1] if needed. */ -# if __LT_SPINLOCK_INIT !=0 - __pthread_handles[0 ].h_lock = __LOCK_INITIALIZER; - __pthread_handles[1 ].h_lock = __LOCK_INITIALIZER; +# ifdef __LT_INITIALIZER_NOT_ZERO + __pthread_handles[0 ].h_lock = __LOCK_ALT_INITIALIZER; + __pthread_handles[1 ].h_lock = __LOCK_ALT_INITIALIZER;# endif # ifndef SHARED /* Unlike in the dynamically linked case the dynamic linker has not
@@ -366,7 +366,7 @@# endif /* self->p_start_args need not be initialized, it's all zero. */ self->p_userstack =1 ; -# if __LT_SPINLOCK_INIT !=0 +# ifdef __LT_INITIALIZER_NOT_ZERO self->p_resume_count = (struct pthread_atomic ) __ATOMIC_INITIALIZER;# endif self->p_alloca_cutoff = __MAX_ALLOCA_CUTOFF;
@@ -380,9 +380,9 @@#else /* USE_TLS */ /* First of all init __pthread_handles[0] and [1]. */ -# if __LT_SPINLOCK_INIT !=0 - __pthread_handles[0 ].h_lock = __LOCK_INITIALIZER; - __pthread_handles[1 ].h_lock = __LOCK_INITIALIZER; +# ifdef __LT_INITIALIZER_NOT_ZERO + __pthread_handles[0 ].h_lock = __LOCK_ALT_INITIALIZER; + __pthread_handles[1 ].h_lock = __LOCK_ALT_INITIALIZER;# endif __pthread_handles[0 ].h_descr = &__pthread_initial_thread; __pthread_handles[1 ].h_descr = &__pthread_manager_thread;
linuxthreads/spinlock.c +12 -12
@@ -24,9 +24,9 @@#include "spinlock.h" #include "restart.h" -static void __pthread_acquire (int * spinlock); +static void __pthread_acquire (__atomic_lock_t * spinlock); -static inline void __pthread_release (int * spinlock) +static inline void __pthread_release (__atomic_lock_t * spinlock) {WRITE_MEMORY_BARRIER (); *spinlock = __LT_SPINLOCK_INIT;
@@ -269,11 +269,11 @@struct wait_node {struct wait_node *next;/* Next node in null terminated linked list */ pthread_descr thr;/* The thread waiting with this node */ -int abandoned;/* Atomic flag */ +__atomic_lock_t abandoned;/* Atomic flag */ };static long wait_node_free_list; -static int wait_node_free_list_spinlock; +__pthread_lock_define_initialized (static, wait_node_free_list_spinlock);/* Allocate a new node from the head of the free list using an atomic operation, or else using malloc if that list is empty. A fundamental
@@ -376,7 +376,7 @@if (self ==NULL ) self =thread_self (); - wait_node.abandoned =0 ; + wait_node.abandoned = __LT_SPINLOCK_INIT; wait_node.next = (struct wait_node *) lock->__status; wait_node.thr = self; lock->__status = (long ) &wait_node;
@@ -402,7 +402,7 @@ wait_node.thr = self; newstatus = (long ) &wait_node; } - wait_node.abandoned =0 ; + wait_node.abandoned = __LT_SPINLOCK_INIT; wait_node.next = (struct wait_node *) oldstatus;/* Make sure the store in wait_node.next completes before performing the compare-and-swap */
@@ -451,7 +451,7 @@if (self ==NULL ) self =thread_self (); - p_wait_node->abandoned =0 ; + p_wait_node->abandoned = __LT_SPINLOCK_INIT; p_wait_node->next = (struct wait_node *) lock->__status; p_wait_node->thr = self; lock->__status = (long ) p_wait_node;
@@ -474,7 +474,7 @@ p_wait_node->thr = self; newstatus = (long ) p_wait_node; } - p_wait_node->abandoned =0 ; + p_wait_node->abandoned = __LT_SPINLOCK_INIT; p_wait_node->next = (struct wait_node *) oldstatus;/* Make sure the store in wait_node.next completes before performing the compare-and-swap */
@@ -574,7 +574,7 @@while (p_node != (struct wait_node *)1 ) {int prio; -if (p_node->abandoned) { +if (lock_held (&p_node->abandoned)) {/* Remove abandoned node. */ #if definedTEST_FOR_COMPARE_AND_SWAP if (!__pthread_has_cas)
@@ -605,7 +605,7 @@ p_max_prio = p_node; } -/* This canno6 jump backward in the list, so no further read +/* This cannot jump backward in the list, so no further read barrier is needed. */ pp_node = &p_node->next; p_node = *pp_node;
@@ -662,7 +662,7 @@#if !definedHAS_COMPARE_AND_SWAP || definedTEST_FOR_COMPARE_AND_SWAP int __pthread_compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock) +__atomic_lock_t * spinlock) {int res;
@@ -699,7 +699,7 @@- When nanosleep() returns, we try again, doing MAX_SPIN_COUNT sched_yield(), then sleeping again if needed. */ -static void __pthread_acquire (int * spinlock) +static void __pthread_acquire (__atomic_lock_t * spinlock) {int cnt =0 ;struct timespec tm;
linuxthreads/spinlock.h +20 -6
@@ -33,14 +33,28 @@#endif #endif +/* Define lock_held for all arches that don't need a modified copy. */ +#ifndef __LT_INITIALIZER_NOT_ZERO +# define lock_held (p) *(p) +#endif + +/* Initliazers for possibly complex structures */ +#ifdef __LT_INITIALIZER_NOT_ZERO +# define __pthread_lock_define_initialized (CLASS ,NAME ) \ + CLASS __atomic_lock_t NAME = __LT_SPINLOCK_ALT_INIT +#else +# define __pthread_lock_define_initialized (CLASS ,NAME ) \ + CLASS __atomic_lock_t NAME +#endif +#if defined(TEST_FOR_COMPARE_AND_SWAP )extern int __pthread_has_cas;extern int __pthread_compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock); +__atomic_lock_t * spinlock);static inline int compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock) +__atomic_lock_t * spinlock) {if (__builtin_expect (__pthread_has_cas,1 ))return __compare_and_swap (ptr, oldval, newval);
@@ -58,7 +72,7 @@static inline int compare_and_swap_with_release_semantics (long * ptr,long oldval, -long newval,int * spinlock) +long newval,__atomic_lock_t * spinlock) {return __compare_and_swap_with_release_semantics (ptr, oldval, newval);
@@ -67,7 +81,7 @@#endif static inline int compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock) +__atomic_lock_t * spinlock) {return __compare_and_swap (ptr, oldval, newval); }
@@ -75,10 +89,10 @@#else extern int __pthread_compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock); +__atomic_lock_t * spinlock);static inline int compare_and_swap (long * ptr,long oldval,long newval, -int * spinlock) +__atomic_lock_t * spinlock) {return __pthread_compare_and_swap (ptr, oldval, newval, spinlock); }
linuxthreads/sysdeps/hppa/pspinlock.c +13 -16
@@ -24,15 +24,12 @@int __pthread_spin_lock (pthread_spinlock_t *lock) { -unsigned int val; +unsigned int *addr =__ldcw_align (lock); + +while (__ldcw (addr) ==0 ) +while (*addr ==0 ) ; -do - asmvolatile ("ldcw %1,%0" - :"=r" (val),"=m" (*lock) - :"m" (*lock)); -while (!val); - -return 0 ; +return 0 ; }weak_alias (__pthread_spin_lock, pthread_spin_lock)
@@ -40,13 +37,9 @@int __pthread_spin_trylock (pthread_spinlock_t *lock) { -unsigned int val; - - asmvolatile ("ldcw %1,%0" - :"=r" (val),"=m" (*lock) - :"m" (*lock)); +unsigned int *a =__ldcw_align (lock); -return val ?0 :EBUSY ; +return __ldcw (a) ?0 :EBUSY ; }weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
@@ -54,7 +47,9 @@int __pthread_spin_unlock (pthread_spinlock_t *lock) { - *lock =1 ; +unsigned int *a =__ldcw_align (lock); + + *a =1 ;return 0 ; }weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
@@ -66,7 +61,9 @@/* We can ignore the `pshared' parameter. Since we are busy-waiting all processes which can access the memory location `lock' points to can use the spinlock. */ - *lock =1 ; +unsigned int *a =__ldcw_align (lock); + + *a =1 ;return 0 ; }weak_alias (__pthread_spin_init, pthread_spin_init)
linuxthreads/sysdeps/hppa/pt-machine.h +67 -14
107 lines not on this page · raw message
linuxthreads/sysdeps/pthread/bits/libc-lock.h +3 -3
@@ -71,12 +71,12 @@initialized locks must be set to one due to the lack of normal atomic operations.) */ -#if __LT_SPINLOCK_INIT ==0 +#ifdef __LT_INITIALIZER_NOT_ZERO# define __libc_lock_define_initialized (CLASS ,NAME ) \ - CLASS __libc_lock_t NAME; + CLASS __libc_lock_t NAME = PTHREAD_MUTEX_INITIALIZER;#else # define __libc_lock_define_initialized (CLASS ,NAME ) \ - CLASS __libc_lock_t NAME = PTHREAD_MUTEX_INITIALIZER; + CLASS __libc_lock_t NAME;#endif #define __libc_rwlock_define_initialized (CLASS ,NAME ) \
linuxthreads/sysdeps/pthread/bits/pthreadtypes.h +5 -3
@@ -22,12 +22,14 @@#define __need_schedparam#include <bits/sched.h> +typedef int __atomic_lock_t ; +/* Fast locks (not abstract because mutexes and conditions aren't abstract). */ struct _pthread_fastlock { -long int __status;/* "Free" or "taken" or head of waiting list */ -int __spinlock;/* Used by compare_and_swap emulation. Also, -adaptive SMP lock stores spin count here. */ +long int __status;/* "Free" or "taken" or head of waiting list */ +__atomic_lock_t __spinlock;/* Used by compare_and_swap emulation. Also, +adaptive SMP lock stores spin count here. */ };#ifndef _PTHREAD_DESCR_DEFINED
linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h +17 -5
@@ -17,11 +17,23 @@write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* Initialize global spinlocks without cast, generally macro wrapped */ +#define __LT_SPINLOCK_ALT_INIT { { 1, 1, 1, 1, } } +/* Initial value of a spinlock. PA-RISC only implements atomic load and clear so this must be non-zero. */ -#define __LT_SPINLOCK_INIT 1 +#define __LT_SPINLOCK_INIT ((__atomic_lock_t) __LT_SPINLOCK_ALT_INIT) + +/* Macros for lock initializers, not using the above definition. +The above definition is not used in the case that static initializers +use this value. */ +#define __LOCK_INITIALIZER { __LT_SPINLOCK_ALT_INIT, 0 } +#define __ATOMIC_INITIALIZER { 0, __LT_SPINLOCK_ALT_INIT } + +/* Used to initialize _pthread_fastlock's in non-static case */ +#define __LOCK_ALT_INITIALIZER ((struct _pthread_fastlock){ __LT_SPINLOCK_INIT, 0 }) + +/* Tell the rest of the code that the initializer is non-zero without +explaining it's internal structure */ +#define __LT_INITIALIZER_NOT_ZERO -/* Macros for lock initializers, using the above definition. */ -#define __LOCK_INITIALIZER { 0, __LT_SPINLOCK_INIT } -#define __ALT_LOCK_INITIALIZER { 0, __LT_SPINLOCK_INIT } -#define __ATOMIC_INITIALIZER { 0, __LT_SPINLOCK_INIT }
linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/pthreadtypes.h +150 -0
150 lines not on this page · raw message
sysdeps/hppa/dl-fptr.c +6 -4
@@ -30,7 +30,7 @@# include <pt-machine.h> /* Remember, we use 0 to mean that a lock is taken on PA-RISC. */ -static int __hppa_fptr_lock =1 ; +static __atomic_lock_t __hppa_fptr_lock = __LT_SPINLOCK_ALT_INIT;#endif /* Because ld.so is now versioned, these functions can be in their own
@@ -127,7 +127,7 @@#ifdef _LIBC_REENTRANT/* Release the lock. Again, remember, zero means the lock is taken! */ if (mem ==NULL ) - __hppa_fptr_lock =1 ; + __hppa_fptr_lock = __LT_SPINLOCK_INIT;#endif /* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */
@@ -180,7 +180,7 @@#ifdef _LIBC_REENTRANT/* Release the lock. */ - __hppa_fptr_lock =1 ; + __hppa_fptr_lock = __LT_SPINLOCK_INIT;#endif }
@@ -190,6 +190,8 @@Elf32_Addr addr = (Elf32_Addr ) address;struct hppa_fptr *f; + address = (void *)((unsigned long )address &~3 );/* Clear the bottom two bits. See make_fptr. */ +#ifdef _LIBC_REENTRANT/* Make sure we are alone. */ while (testandset (&__hppa_fptr_lock));
@@ -204,7 +206,7 @@#ifdef _LIBC_REENTRANT/* Release the lock. */ - __hppa_fptr_lock =1 ; + __hppa_fptr_lock = __LT_SPINLOCK_INIT;#endif return addr;
#! /bin/sh -e
# DP: Description: Return Malloc to 8-byte alignments.
# DP: Author: Carlos O'Donell <[email protected]>
# DP: Upstream status: Not submitted
# DP: Status Details: Writing Changelog, will get submitted in the next week or so... # DP: Date: March 1st, 2003
# Since GCC can't assure 16-byte alignment in all situations we have moved
# to the much more robust self aligning setup where an alignment of 8-bytes # is perfectly okay. This patch reverts our malloc alignments to 8-bytes and # allows us to have a more optimal situation from the viewpoint of the malloc # algorithm. # # - Carlos.
if [ $# -ne 2 ]; then
echo >&2 "basename $0: script expects -patch|-unpatch as argument" exit 1
fi
case "$1" in
-patch) patch -d "$2" -f --no-backup-if-mismatch -p1 < $0;;
-unpatch) patch -d "$2" -f --no-backup-if-mismatch -R -p1 < $0;;
*)
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1esac
exit 0
# append the patch here and adjust the -p? flag in the patch calls. --- glibc-2.3.1/sysdeps/hppa/Makefile 2003-01-20 23:47:12.000000000 -0500 +++ glibc-2.3.1/sysdeps/hppa/Makefile 2003-01-20 23:47:19.000000000 -0500 @@ -22,10 +22,6 @@ # CFLAGS-.os += -ffunction-sections LDFLAGS-c_pic.os += -Wl,--unique=.text*
-ifeq ($(subdir),malloc)-CFLAGS-malloc.c += -DMALLOC_ALIGNMENT=16
-endif
-
ifeq ($(subdir),elf)
CFLAGS-rtld.c += -mdisable-fpregs
dl-routines += dl-symaddr dl-fptr
At Sun, 2 Mar 2003 11:48:16 -0500,
Quoted 26 lines · Carlos O'Donell
With regards to GNU/Libc 2.3.x
The following is an update of LinuxThreads for HPPA, the changelog is in progress and it has shown no regressions from a testing standpoint. It actually does better in the gcc/g++ testsuite. This work represents some long discussions between John David Anglin and myself, please read the dpatch for more information about a specific patch.
Please remove the following .dpatch files from debian-glibc's CVS:
glibc23-02-hppa-min-kern-unwind-fde.dpatch
glibc23-03-hppa-mcontext.dpatch
glibc23-04-hppa-fcntl64.dpatch
glibc23-05-hppa-buildhack.dpatch
glibc23-06-hppa-tests.dpatch
glibc23-08-hppa-configure.dpatchThey are no longer being used and were superceeded by CVS patches.
Please replace glibc23-00-hppa-pthreads.dpatch with the attached version. Please add glibc23-hppa-malloc-align.dpatch to the list of HPPA patches.
Quick Summary:
- LinuxThreads is now using a self-aligning lock.
- Malloc alignment has been moved back to 8 for optimal performance.
Quoted 8 lines
I did this work over 2-3 weeks ago, but due to current time constraints it was behind "libgcc-compat hppa" on the queue, and thus didn't get out. Randolph Chung recently fixed hppa's
__clz_tablibgcc-compat issue, which means I can take the 5 minutes I need to send this email :)This code has been heavily tested by John and myself, though should any HPPA users find problems, or have comments, please file bugs and/or contact me direclty or via any of the lists :)
Excellent :)
Thanks, but should it apply in 2.3.1-15? I would like to delay to apply it in 2.3.2-1.
Regards,
-- gotom
At Sun, 2 Mar 2003 11:48:16 -0500,
Quoted 26 lines · Carlos O'Donell
With regards to GNU/Libc 2.3.x
The following is an update of LinuxThreads for HPPA, the changelog is in progress and it has shown no regressions from a testing standpoint. It actually does better in the gcc/g++ testsuite. This work represents some long discussions between John David Anglin and myself, please read the dpatch for more information about a specific patch.
Please remove the following .dpatch files from debian-glibc's CVS:
glibc23-02-hppa-min-kern-unwind-fde.dpatch
glibc23-03-hppa-mcontext.dpatch
glibc23-04-hppa-fcntl64.dpatch
glibc23-05-hppa-buildhack.dpatch
glibc23-06-hppa-tests.dpatch
glibc23-08-hppa-configure.dpatchThey are no longer being used and were superceeded by CVS patches.
Please replace glibc23-00-hppa-pthreads.dpatch with the attached version. Please add glibc23-hppa-malloc-align.dpatch to the list of HPPA patches.
Quick Summary:
- LinuxThreads is now using a self-aligning lock.
- Malloc alignment has been moved back to 8 for optimal performance.
Quoted 8 lines
I did this work over 2-3 weeks ago, but due to current time constraints it was behind "libgcc-compat hppa" on the queue, and thus didn't get out. Randolph Chung recently fixed hppa's
__clz_tablibgcc-compat issue, which means I can take the 5 minutes I need to send this email :)This code has been heavily tested by John and myself, though should any HPPA users find problems, or have comments, please file bugs and/or contact me direclty or via any of the lists :)
Excellent :)
Thanks, but should it apply in 2.3.1-15? I would like to delay to apply it in 2.3.2-1.
Regards,
-- gotom
Quoted 4 lines
Excellent :)
Thanks, but should it apply in 2.3.1-15? I would like to delay to apply it in 2.3.2-1.
It will work with -15, HPPA will FTBS under 2.3.2-1 because we haven't written the sysdep-cancel support yet. The timeline for that looks like atleast 2 weeks.
c.
Quoted 4 lines
Excellent :)
Thanks, but should it apply in 2.3.1-15? I would like to delay to apply it in 2.3.2-1.
It will work with -15, HPPA will FTBS under 2.3.2-1 because we haven't written the sysdep-cancel support yet. The timeline for that looks like atleast 2 weeks.
c.