All of lore.kernel.org
 help / color / mirror / Atom feed
From: Carlos O'Donell <carlos@baldric.uwo.ca>
To: libc-alpha@sources.redhat.com
Cc: debian-glibc@lists.debian.org, parisc-linux@lists.parisc-linux.org
Subject: [parisc-linux] [PATCH] Implement linuxthreads on HPPA
Date: Tue, 19 Nov 2002 01:06:20 -0500	[thread overview]
Message-ID: <20021119060620.GE12451@systemhalted> (raw)

[-- Attachment #1: Type: text/plain, Size: 4453 bytes --]


libc-alpha,

I've reworked the hppa pthreads patch to be as low impact as possible :)
Though some things need to be done, namely, hppa needs the lock variable
to be 16-byte aligned. This alignment requirement means all sorts of ugly
things, from wrappers to avoid non-constant named initializers, to the use
of a struct for a lock variable.

Thanks for all your feedback.

My apologies for the slow return, school called :}

c.

Round 2 ...

 linuxthreads/descr.h                                          |    2 
 linuxthreads/pt-machine.c                                     |    4 
 linuxthreads/pthread.c                                        |   16 -
 linuxthreads/spinlock.c                                       |   24 -
 linuxthreads/spinlock.h                                       |   26 +
 linuxthreads/sysdeps/hppa/pspinlock.c                         |   24 -
 linuxthreads/sysdeps/hppa/pt-machine.h                        |   46 ++-
 linuxthreads/sysdeps/pthread/bits/libc-lock.h                 |    6 
 linuxthreads/sysdeps/pthread/bits/pthreadtypes.h              |    8 
 linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h     |   22 +
 linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/pthreadtypes.h |  146 ++++++++++
 linuxthreads/sysdeps/unix/sysv/linux/hppa/pt-initfini.c       |  132 ++++-----
 sysdeps/hppa/dl-fptr.c                                        |   10 
 13 files changed, 336 insertions(+), 130 deletions(-)

---

2002-11-11  Carlos O'Donell  <carlos@baldric.uwo.ca>

	* linuxthreads/descr.h: Change spinlock type to __atomic_lock_t.
	* linuxthreads/pt-machine.c: Change extern definition of testandset
	so it uses __atomic_lock_t instead of int.
	* linuxthreads/pthread.c:
	(__pthread_initialize_minimal): Replace the use of __LT_SPINLOCK_INIT
	with __LT_INITIALIZER_NOT_ZERO in cases where it is used to check 
	wether the initialization should occur or not.
	(__pthread_initialize_manager): Likewise.
	* linuxthreads/spinlock.h: Add default define for lock_held if it has 
	not already been defined. Create the __pthread_lock_define_initialized
	macro to wrap up the use of an alternate initializer. Change 
	__pthread_compare_and_swap to use __atomic_lock_t,
	(compare_and_swap): Change function definitions to use __atomic_lock_t
	(compare_and_swap_with_release_semantics): Likewise.
	(__pthread_compare_and_swap): Likewise.
	* linuxthreads/spinlock.c: Change definition of __pthread_acquire to 
	use __atomic_lock_t. Modify struct wait_node to use __atomic_lock_t 
	as lock. Wrap definition and init of wait_node_free_list_spinlock in 
	macro.
	(__pthread_release): Change function definition to use __atomic_lock_t
	(__pthread_alt_lock): Change instances of abandoned = 0 to
	abandoned = __LT_SPINLOCK_INIT.
	(__pthread_alt_timedlock): Likewise.
	(__pthread_alt_unlock): Use lock_held instead of just checking 
	abandoned == 0. Typo fix in comment from "canno6" to "cannot"
	(__pthread_compare_and_swap): Change function definition to use 
	__atomic_lock_t.
	(__pthread_acquire): Likewise.
	* linuxthreads/sysdeps/hppa/pspinlock.c: Define __ldcw macro for PA's
	single atomic operation.
	(__pthread_spin_lock): Modified to use __ldcw macro.
	(__pthread_spin_trylock): Likewise.
	* linuxthreads/sysdeps/hppa/pt-machine.h: Add sys/types.h to pull in
	__atomic_long_t definition. Remove extern testandset define. Add 
	defines for FLOATING_STACKS and ARACH_STACK_MAX_SIZE. Add lock_held
	macro.
	(__get_cr27): New.
	(__set_cr27): New.
	(__load_and_clear): New.
	(testandset): Modified to emulate testandset using __load_and_clear.
	* linuxthreads/sysdeps/pthread/bits/libc-lock.h: Replace the use of
	__LT_SPINLOCK_INIT with that of __LT_INITIALIZER_NOT_ZERO.
	* linuxthreads/sysdeps/pthread/bits/pthreadtypes.h:
	Define default __atomic_lock_t to be an int. Change struct
	_pthread_fastlock to reflect name change.
	* linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h:
	Change macro's to reflect that lock is actually struct.
	* linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/pthreadtypes.h: New.
	* linuxthreads/sysdeps/unix/sysv/linux/hppa/pt-initfini.c: 
	Avoid unterminated string literals.
	* sysdeps/hppa/dl-fptr.c: Change global lock to use 
	__LT_SPINLOCK_ALT_INIT.
	(__hppa_make_fptr): Use __LT_SPINLOCK_INIT to clear locks.
	(_dl_unmap): Likewise.
	(_dl_lookup_address): Likewise, and clear bottom two bits of address
	to fix function pointer calculation, see make_ftpr for the reasoning.


[-- Attachment #2: 00-glibc23-hppa-pthreads --]
[-- Type: text/plain, Size: 25798 bytes --]

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	2002-10-09 05:10:55.000000000 -0400
+++ glibc-2.3.1/linuxthreads/descr.h	2002-11-03 16:57:02.000000000 -0500
@@ -61,7 +61,7 @@
 /* Atomic counter made possible by compare_and_swap */
 struct pthread_atomic {
   long p_count;
-  int p_spinlock;
+  __atomic_lock_t p_spinlock;
 };
 
 
diff -urN glibc-2.3.1.orig/linuxthreads/pt-machine.c glibc-2.3.1/linuxthreads/pt-machine.c
--- glibc-2.3.1.orig/linuxthreads/pt-machine.c	2002-08-26 18:39:45.000000000 -0400
+++ glibc-2.3.1/linuxthreads/pt-machine.c	2002-11-09 19:03:50.000000000 -0500
@@ -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>
diff -urN glibc-2.3.1.orig/linuxthreads/pthread.c glibc-2.3.1/linuxthreads/pthread.c
--- glibc-2.3.1.orig/linuxthreads/pthread.c	2002-10-11 06:53:15.000000000 -0400
+++ glibc-2.3.1/linuxthreads/pthread.c	2002-11-07 09:39:12.000000000 -0500
@@ -309,9 +309,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
@@ -334,7 +334,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;
@@ -346,9 +346,9 @@
   __pthread_handles[0].h_descr = self;
 #else
   /* 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;
@@ -572,7 +572,7 @@
 # endif
   tcb->p_start_args = (struct pthread_start_args) PTHREAD_START_ARGS_INITIALIZER(__pthread_manager);
   tcb->p_nr = 1;
-# if __LT_SPINLOCK_INIT != 0
+# ifdef __LT_INITIALIZER_NOT_ZERO 
   self->p_resume_count = (struct pthread_atomic) __ATOMIC_INITIALIZER;
 # endif
   tcb->p_alloca_cutoff = PTHREAD_STACK_MIN / 4;
diff -urN glibc-2.3.1.orig/linuxthreads/spinlock.c glibc-2.3.1/linuxthreads/spinlock.c
--- glibc-2.3.1.orig/linuxthreads/spinlock.c	2002-08-29 06:32:19.000000000 -0400
+++ glibc-2.3.1/linuxthreads/spinlock.c	2002-11-09 14:51:45.000000000 -0500
@@ -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 defined TEST_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 !defined HAS_COMPARE_AND_SWAP || defined TEST_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;
diff -urN glibc-2.3.1.orig/linuxthreads/spinlock.h glibc-2.3.1/linuxthreads/spinlock.h
--- glibc-2.3.1.orig/linuxthreads/spinlock.h	2001-05-24 19:36:35.000000000 -0400
+++ glibc-2.3.1/linuxthreads/spinlock.h	2002-11-10 13:33:43.000000000 -0500
@@ -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);
 }
diff -urN glibc-2.3.1.orig/linuxthreads/sysdeps/hppa/pspinlock.c glibc-2.3.1/linuxthreads/sysdeps/hppa/pspinlock.c
--- glibc-2.3.1.orig/linuxthreads/sysdeps/hppa/pspinlock.c	2002-08-26 18:39:51.000000000 -0400
+++ glibc-2.3.1/linuxthreads/sysdeps/hppa/pspinlock.c	2002-11-03 16:57:02.000000000 -0500
@@ -21,18 +21,20 @@
 #include <pthread.h>
 #include "internals.h"
 
+/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*.  */
+#define __ldcw(a) ({ \
+	unsigned __ret; \
+	__asm__ __volatile__("ldcw 0(%1),%0" : "=r" (__ret) : "r" (a)); \
+	__ret; \
+})
+
 int
 __pthread_spin_lock (pthread_spinlock_t *lock)
 {
-  unsigned int val;
-
-  do
-    asm volatile ("ldcw %1,%0"
-		  : "=r" (val), "=m" (*lock)
-		  : "m" (*lock));
-  while (!val);
+	while (__ldcw (*lock) == 0)
+		while (*lock == 0) ;
 
-  return 0;
+	return 0;
 }
 weak_alias (__pthread_spin_lock, pthread_spin_lock)
 
@@ -40,11 +42,7 @@
 int
 __pthread_spin_trylock (pthread_spinlock_t *lock)
 {
-  unsigned int val;
-
-  asm volatile ("ldcw %1,%0"
-		: "=r" (val), "=m" (*lock)
-		: "m" (*lock));
+  unsigned int val = __ldcw(*lock);
 
   return val ? 0 : EBUSY;
 }
diff -urN glibc-2.3.1.orig/linuxthreads/sysdeps/hppa/pt-machine.h glibc-2.3.1/linuxthreads/sysdeps/hppa/pt-machine.h
--- glibc-2.3.1.orig/linuxthreads/sysdeps/hppa/pt-machine.h	2002-08-26 18:39:51.000000000 -0400
+++ glibc-2.3.1/linuxthreads/sysdeps/hppa/pt-machine.h	2002-11-11 13:45:29.000000000 -0500
@@ -22,13 +22,13 @@
 #ifndef _PT_MACHINE_H
 #define _PT_MACHINE_H   1
 
+#include <sys/types.h>
 #include <bits/initspin.h>
 
 #ifndef PT_EI
 # define PT_EI extern inline
 #endif
 
-extern long int testandset (int *spinlock);
 extern int __compare_and_swap (long int *p, long int oldval, long int newval);
 
 /* Get some notion of the current stack.  Need not be exactly the top
@@ -36,16 +36,39 @@
 #define CURRENT_STACK_FRAME  stack_pointer
 register char * stack_pointer __asm__ ("%r30");
 
+/* Get/Set thread-specific pointer.  We have to call into the kernel to
+ * modify it, but we can read it in user mode.  */
+
+#define THREAD_SELF __get_cr27()
+
+static inline struct _pthread_descr_struct * __get_cr27(void)
+{
+	long cr27;
+	asm("mfctl %%cr27, %0" : "=r" (cr27) : );
+	return (struct _pthread_descr_struct *) cr27;
+}
+
+#define INIT_THREAD_SELF(descr, nr) __set_cr27(descr)
+
+static inline void __set_cr27(struct _pthread_descr_struct * cr27)
+{
+	asm(
+		"ble	0xe0(%%sr2, %%r0)\n\t"
+		"copy	%0, %%r26"
+	 : : "r" (cr27) : "r26" );
+}
+
+/* We want the OS to assign stack addresses.  */
+#define FLOATING_STACKS	1
+#define ARCH_STACK_MAX_SIZE	8*1024*1024
 
 /* The hppa only has one atomic read and modify memory operation,
    load and clear, so hppa spinlocks must use zero to signify that
    someone is holding the lock.  */
 
-#define xstr(s) str(s)
-#define str(s) #s
 /* Spinlock implementation; required.  */
-PT_EI long int
-testandset (int *spinlock)
+PT_EI int
+__load_and_clear(__atomic_lock_t *spinlock)
 {
   int ret;
 
@@ -54,9 +77,16 @@
        : "=r"(ret), "=m"(*spinlock)
        : "r"(spinlock));
 
-  return ret == 0;
+  return ret;
+}
+
+/* Emulate testandset */
+PT_EI long int
+testandset(__atomic_lock_t *spinlock)
+{
+	return (__load_and_clear(spinlock) == 0);
 }
-#undef str
-#undef xstr
 
+#define lock_held(spinlock) ((spinlock)->lock==0)
+		
 #endif /* pt-machine.h */
diff -urN glibc-2.3.1.orig/linuxthreads/sysdeps/pthread/bits/libc-lock.h glibc-2.3.1/linuxthreads/sysdeps/pthread/bits/libc-lock.h
--- glibc-2.3.1.orig/linuxthreads/sysdeps/pthread/bits/libc-lock.h	2002-10-11 06:53:17.000000000 -0400
+++ glibc-2.3.1/linuxthreads/sysdeps/pthread/bits/libc-lock.h	2002-11-06 21:44:40.000000000 -0500
@@ -64,12 +64,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) \
diff -urN glibc-2.3.1.orig/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h glibc-2.3.1/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h
--- glibc-2.3.1.orig/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h	2001-01-27 01:26:13.000000000 -0500
+++ glibc-2.3.1/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h	2002-11-03 16:57:02.000000000 -0500
@@ -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
diff -urN glibc-2.3.1.orig/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h glibc-2.3.1/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h
--- glibc-2.3.1.orig/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h	2002-08-26 18:39:55.000000000 -0400
+++ glibc-2.3.1/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h	2002-11-09 12:47:16.000000000 -0500
@@ -19,9 +19,21 @@
 
 /* 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){ 1 })
+
+/* Initillize global spinlocks without cast, generally macro wrapped */
+#define __LT_SPINLOCK_ALT_INIT { 1 }
+
+/* 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 { { 1 }, 0 }
+#define __ATOMIC_INITIALIZER { 0, { 1 } }
+
+/* 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 }
diff -urN glibc-2.3.1.orig/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/pthreadtypes.h glibc-2.3.1/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/pthreadtypes.h
--- glibc-2.3.1.orig/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/pthreadtypes.h	1969-12-31 19:00:00.000000000 -0500
+++ glibc-2.3.1/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/pthreadtypes.h	2002-11-03 16:57:02.000000000 -0500
@@ -0,0 +1,146 @@
+/* Linuxthreads - a simple clone()-based implementation of Posix        */
+/* threads for Linux.                                                   */
+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr)              */
+/*                                                                      */
+/* This program is free software; you can redistribute it and/or        */
+/* modify it under the terms of the GNU Library General Public License  */
+/* as published by the Free Software Foundation; either version 2       */
+/* of the License, or (at your option) any later version.               */
+/*                                                                      */
+/* This program 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 Library General Public License for more details.                 */
+
+#if !defined _BITS_TYPES_H && !defined _PTHREAD_H
+# error "Never include <bits/pthreadtypes.h> directly; use <sys/types.h> instead."
+#endif
+
+#ifndef _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H	1
+
+#define __need_schedparam
+#include <bits/sched.h>
+
+typedef struct {
+	int lock;
+} __attribute__((aligned (16))) __atomic_lock_t;
+
+/* Fast locks (not abstract because mutexes and conditions aren't abstract). */
+struct _pthread_fastlock
+{
+  __atomic_lock_t __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 */
+};
+
+#ifndef _PTHREAD_DESCR_DEFINED
+/* Thread descriptors */
+typedef struct _pthread_descr_struct *_pthread_descr;
+# define _PTHREAD_DESCR_DEFINED
+#endif
+
+
+/* Attributes for threads.  */
+typedef struct __pthread_attr_s
+{
+  int __detachstate;
+  int __schedpolicy;
+  struct __sched_param __schedparam;
+  int __inheritsched;
+  int __scope;
+  size_t __guardsize;
+  int __stackaddr_set;
+  void *__stackaddr;
+  size_t __stacksize;
+} pthread_attr_t;
+
+
+/* Conditions (not abstract because of PTHREAD_COND_INITIALIZER */
+typedef struct
+{
+  struct _pthread_fastlock __c_lock; /* Protect against concurrent access */
+  _pthread_descr __c_waiting;        /* Threads waiting on this condition */
+} pthread_cond_t;
+
+
+/* Attribute for conditionally variables.  */
+typedef struct
+{
+  int __dummy;
+} pthread_condattr_t;
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Mutexes (not abstract because of PTHREAD_MUTEX_INITIALIZER).  */
+/* (The layout is unnatural to maintain binary compatibility
+    with earlier releases of LinuxThreads.) */
+typedef struct
+{
+  int __m_reserved;               /* Reserved for future use */
+  int __m_count;                  /* Depth of recursive locking */
+  _pthread_descr __m_owner;       /* Owner thread (if recursive or errcheck) */
+  int __m_kind;                   /* Mutex kind: fast, recursive or errcheck */
+  struct _pthread_fastlock __m_lock; /* Underlying fast lock */
+} pthread_mutex_t;
+
+
+/* Attribute for mutex.  */
+typedef struct
+{
+  int __mutexkind;
+} pthread_mutexattr_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#ifdef __USE_UNIX98
+/* Read-write locks.  */
+typedef struct _pthread_rwlock_t
+{
+  struct _pthread_fastlock __rw_lock; /* Lock to guarantee mutual exclusion */
+  int __rw_readers;                   /* Number of readers */
+  _pthread_descr __rw_writer;         /* Identity of writer, or NULL if none */
+  _pthread_descr __rw_read_waiting;   /* Threads waiting for reading */
+  _pthread_descr __rw_write_waiting;  /* Threads waiting for writing */
+  int __rw_kind;                      /* Reader/Writer preference selection */
+  int __rw_pshared;                   /* Shared between processes or not */
+} pthread_rwlock_t;
+
+
+/* Attribute for read-write locks.  */
+typedef struct
+{
+  int __lockkind;
+  int __pshared;
+} pthread_rwlockattr_t;
+#endif
+
+#ifdef __USE_XOPEN2K
+/* POSIX spinlock data type.  */
+typedef volatile int pthread_spinlock_t __attribute__((aligned (16)));
+
+/* POSIX barrier. */
+typedef struct {
+  struct _pthread_fastlock __ba_lock; /* Lock to guarantee mutual exclusion */
+  int __ba_required;                  /* Threads needed for completion */
+  int __ba_present;                   /* Threads waiting */
+  _pthread_descr __ba_waiting;        /* Queue of waiting threads */
+} pthread_barrier_t;
+
+/* barrier attribute */
+typedef struct {
+  int __pshared;
+} pthread_barrierattr_t;
+
+#endif
+
+
+/* Thread identifiers */
+typedef unsigned long int pthread_t;
+
+#endif	/* bits/pthreadtypes.h */
diff -urN glibc-2.3.1.orig/linuxthreads/sysdeps/unix/sysv/linux/hppa/pt-initfini.c glibc-2.3.1/linuxthreads/sysdeps/unix/sysv/linux/hppa/pt-initfini.c
--- glibc-2.3.1.orig/linuxthreads/sysdeps/unix/sysv/linux/hppa/pt-initfini.c	2002-08-26 18:39:29.000000000 -0400
+++ glibc-2.3.1/linuxthreads/sysdeps/unix/sysv/linux/hppa/pt-initfini.c	2002-11-11 13:36:31.000000000 -0500
@@ -41,70 +41,70 @@
    and epilogues.  Therefore we write these in assembly to make sure
    they do the right thing.  */
 
-__asm__ ("
-
-#include \"defs.h\"
-
-/*@HEADER_ENDS*/
-
-/*@_init_PROLOG_BEGINS*/
-	.section .init
-	.align 4
-	.globl _init
-	.type _init,@function
-_init:
-	stw	%rp,-20(%sp)
-	stwm	%r4,64(%sp)
-	stw	%r19,-32(%sp)
-	bl	__pthread_initialize_minimal,%rp
-	copy	%r19,%r4	/* delay slot */
-	copy	%r4,%r19
-/*@_init_PROLOG_ENDS*/
-
-/*@_init_EPILOG_BEGINS*/
-/* Here is the tail end of _init.  */
-	.section .init
-	ldw	-84(%sp),%rp
-	copy	%r4,%r19
-	bv	%r0(%rp)
-_end_init:
-	ldwm	-64(%sp),%r4
-
-/* Our very own unwind info, because the assembler can't handle
-   functions split into two or more pieces.  */
-	.section .PARISC.unwind,\"a\",@progbits
-	.extern _init
-	.word	_init, _end_init
-	.byte	0x08, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08
-
-/*@_init_EPILOG_ENDS*/
-
-/*@_fini_PROLOG_BEGINS*/
-	.section .fini
-	.align 4
-	.globl _fini
-	.type _fini,@function
-_fini:
-	stw	%rp,-20(%sp)
-	stwm	%r4,64(%sp)
-	stw	%r19,-32(%sp)
-	copy	%r19,%r4
-/*@_fini_PROLOG_ENDS*/
-
-/*@_fini_EPILOG_BEGINS*/
-	.section .fini
-	ldw	-84(%sp),%rp
-	copy	%r4,%r19
-	bv	%r0(%rp)
-_end_fini:
-	ldwm	-64(%sp),%r4
-
-	.section .PARISC.unwind,\"a\",@progbits
-	.extern _fini
-	.word	_fini, _end_fini
-	.byte	0x08, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08
-
-/*@_fini_EPILOG_ENDS*/
-
-/*@TRAILER_BEGINS*/
+__asm__ ("								\n\
+									\n\
+#include \"defs.h\"							\n\
+									\n\
+/*@HEADER_ENDS*/							\n\
+									\n\
+/*@_init_PROLOG_BEGINS*/						\n\
+	.section .init							\n\
+	.align 4							\n\
+	.globl _init							\n\
+	.type _init,@function						\n\
+_init:									\n\
+	stw	%rp,-20(%sp)						\n\
+	stwm	%r4,64(%sp)						\n\
+	stw	%r19,-32(%sp)						\n\
+	bl	__pthread_initialize_minimal,%rp			\n\
+	copy	%r19,%r4	/* delay slot */			\n\
+	copy	%r4,%r19						\n\
+/*@_init_PROLOG_ENDS*/							\n\
+									\n\
+/*@_init_EPILOG_BEGINS*/						\n\
+/* Here is the tail end of _init.  */					\n\
+	.section .init							\n\
+	ldw	-84(%sp),%rp						\n\
+	copy	%r4,%r19						\n\
+	bv	%r0(%rp)						\n\
+_end_init:								\n\
+	ldwm	-64(%sp),%r4						\n\
+									\n\
+/* Our very own unwind info, because the assembler can't handle		\n\
+   functions split into two or more pieces.  */				\n\
+	.section .PARISC.unwind,\"a\",@progbits				\n\
+	.extern _init							\n\
+	.word	_init, _end_init					\n\
+	.byte	0x08, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08		\n\
+									\n\
+/*@_init_EPILOG_ENDS*/							\n\
+									\n\
+/*@_fini_PROLOG_BEGINS*/						\n\
+	.section .fini							\n\
+	.align 4							\n\
+	.globl _fini							\n\
+	.type _fini,@function						\n\
+_fini:									\n\
+	stw	%rp,-20(%sp)						\n\
+	stwm	%r4,64(%sp)						\n\
+	stw	%r19,-32(%sp)						\n\
+	copy	%r19,%r4						\n\
+/*@_fini_PROLOG_ENDS*/							\n\
+									\n\
+/*@_fini_EPILOG_BEGINS*/						\n\
+	.section .fini							\n\
+	ldw	-84(%sp),%rp						\n\
+	copy	%r4,%r19						\n\
+	bv	%r0(%rp)						\n\
+_end_fini:								\n\
+	ldwm	-64(%sp),%r4						\n\
+									\n\
+	.section .PARISC.unwind,\"a\",@progbits				\n\
+	.extern _fini							\n\
+	.word	_fini, _end_fini					\n\
+	.byte	0x08, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08		\n\
+									\n\
+/*@_fini_EPILOG_ENDS*/							\n\
+									\n\
+/*@TRAILER_BEGINS*/							\n\
 ");
diff -urN glibc-2.3.1.orig/sysdeps/hppa/dl-fptr.c glibc-2.3.1/sysdeps/hppa/dl-fptr.c
--- glibc-2.3.1.orig/sysdeps/hppa/dl-fptr.c	2002-01-31 20:31:51.000000000 -0500
+++ glibc-2.3.1/sysdeps/hppa/dl-fptr.c	2002-11-11 13:39:11.000000000 -0500
@@ -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;

             reply	other threads:[~2002-11-19  6:06 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-11-19  6:06 Carlos O'Donell [this message]
  -- strict thread matches above, loose matches on Subject: below --
2002-11-19  6:06 [parisc-linux] [PATCH] Implement linuxthreads on HPPA Carlos O'Donell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20021119060620.GE12451@systemhalted \
    --to=carlos@baldric.uwo.ca \
    --cc=debian-glibc@lists.debian.org \
    --cc=libc-alpha@sources.redhat.com \
    --cc=parisc-linux@lists.parisc-linux.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.