This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PA-RISC diffs, part 4: non-zero spinlock initializers in LinuxThreads


Because HP, in their infinite wisdom, only gave us a single atomic
operation on PA-RISC, and because they also made it *backwards*, we
need to initialize spinlocks to non-zero, and release spinlocks by
storing non-zero to them.

Of course, in its infinite wisdom, the generic LinuxThreads code
assumes that unheld spinlocks are always zero.

This patch fixes that, while still keeping initialized locks in .bss on
normal platforms.

2000-10-12  Alan Modra <alan@linuxcare.com.au>
	
	* linuxthreads/sysdeps/pthread/initspin.h: New file.
	* linuxthreads/spinlock.h: Move LOCK_INITIALIZER definition to
	<bits/initspin.h>.
	(__pthread_init_lock): Initialize lock with LT_SPINLOCK_INIT.
	(__pthread_alt_init_lock): Likewise.
	(__pthread_alt_trylock): Release lock with LT_SPINLOCK_INIT.

2000-10-12  David Huggins-Daines  <dhd@linuxcare.com>

	* linuxthreads/oldsemaphore.c (__old_sem_init): Release lock with
	LT_SPINLOCK_INIT, not zero.
	* linuxthreads/spinlock.c (__pthread_unlock): Likewise.
	(__pthread_alt_lock): Likewise.
	(__pthread_alt_timedlock): Likewise.
	(__pthread_alt_unlock): Likewise.
	* linuxthreads/sysdeps/pthread/bits/libc-lock.h: Initialize locks
	with LT_SPINLOCK_INIT if it is non-zero.  Likewise for init-once
	flags.
	* sysdeps/unix/sysv/linux/Makefile: Include <bits/initspin> in
	$(sysdep_headers).
	* sysdeps/unix/sysv/linux/bits/initspin.h: Dummy version for
	non-threaded platforms.


diff -urN --exclude=configure --exclude=.cvsignore --exclude=CVS --exclude=*.texi --exclude=texis --exclude=*.info* --exclude=*~ glibc-2.1.95/linuxthreads/oldsemaphore.c glibc/linuxthreads/oldsemaphore.c
--- glibc-2.1.95/linuxthreads/oldsemaphore.c	Fri Apr  7 15:09:23 2000
+++ glibc/linuxthreads/oldsemaphore.c	Tue Oct  3 13:11:02 2000
@@ -65,7 +65,7 @@
 	errno = ENOSYS;
 	return -1;
     }
-  sem->sem_spinlock = 0;
+  sem->sem_spinlock = LT_SPINLOCK_INIT;
   sem->sem_status = ((long)value << 1) + 1;
   return 0;
 }
diff -urN --exclude=configure --exclude=.cvsignore --exclude=CVS --exclude=*.texi --exclude=texis --exclude=*.info* --exclude=*~ glibc-2.1.95/linuxthreads/spinlock.c glibc/linuxthreads/spinlock.c
--- glibc-2.1.95/linuxthreads/spinlock.c	Wed Aug  2 17:52:13 2000
+++ glibc/linuxthreads/spinlock.c	Thu Oct  5 15:03:15 2000
@@ -155,7 +155,7 @@
 #if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP
   {
     WRITE_MEMORY_BARRIER();
-    lock->__spinlock = 0;
+    lock->__spinlock = LT_SPINLOCK_INIT;
     return 0;
   }
 #endif
@@ -394,7 +394,7 @@
     }
 
     WRITE_MEMORY_BARRIER();
-    lock->__spinlock = 0;
+    lock->__spinlock = LT_SPINLOCK_INIT;
 
     if (suspend_needed)
       suspend (self);
@@ -468,7 +468,7 @@
     }
 
     WRITE_MEMORY_BARRIER();
-    lock->__spinlock = 0;
+    lock->__spinlock = LT_SPINLOCK_INIT;
     goto suspend;
   }
 #endif
@@ -649,7 +649,7 @@
 #if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP
   {
     WRITE_MEMORY_BARRIER();
-    lock->__spinlock = 0;
+    lock->__spinlock = LT_SPINLOCK_INIT;
   }
 #endif
 }
diff -urN --exclude=configure --exclude=.cvsignore --exclude=CVS --exclude=*.texi --exclude=texis --exclude=*.info* --exclude=*~ glibc-2.1.95/linuxthreads/spinlock.h glibc/linuxthreads/spinlock.h
--- glibc-2.1.95/linuxthreads/spinlock.h	Thu Sep  7 14:56:28 2000
+++ glibc/linuxthreads/spinlock.h	Thu Oct  5 15:00:40 2000
@@ -12,6 +12,8 @@
 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        */
 /* GNU Library General Public License for more details.                 */
 
+#include <bits/initspin.h>
+
 
 /* There are 2 compare and swap synchronization primitives with
    different semantics:
@@ -97,7 +99,7 @@
 static inline void __pthread_init_lock(struct _pthread_fastlock * lock)
 {
   lock->__status = 0;
-  lock->__spinlock = 0;
+  lock->__spinlock = LT_SPINLOCK_INIT;
 }
 
 static inline int __pthread_trylock (struct _pthread_fastlock * lock)
@@ -139,7 +141,7 @@
 static inline void __pthread_alt_init_lock(struct _pthread_fastlock * lock)
 {
   lock->__status = 0;
-  lock->__spinlock = 0;
+  lock->__spinlock = LT_SPINLOCK_INIT;
 }
 
 static inline int __pthread_alt_trylock (struct _pthread_fastlock * lock)
@@ -163,7 +165,7 @@
 	    WRITE_MEMORY_BARRIER();
 	    res = 0;
 	  }
-	lock->__spinlock = 0;
+	lock->__spinlock = LT_SPINLOCK_INIT;
       }
     return res;
   }
@@ -178,11 +180,6 @@
 #endif
 }
 
-/* Initializers for both lock variants */
-
-#define LOCK_INITIALIZER {0, 0}
-#define ALT_LOCK_INITIALIZER {0, 0}
-
 /* Operations on pthread_atomic, which is defined in internals.h */
 
 static inline long atomic_increment(struct pthread_atomic *pa)
@@ -207,8 +204,6 @@
 
     return oldval;
 }
-
-#define ATOMIC_INITIALIZER { 0, 0 }
 
 
 static inline void
diff -urN --exclude=configure --exclude=.cvsignore --exclude=CVS --exclude=*.texi --exclude=texis --exclude=*.info* --exclude=*~ glibc-2.1.95/linuxthreads/sysdeps/pthread/bits/initspin.h glibc/linuxthreads/sysdeps/pthread/bits/initspin.h
--- glibc-2.1.95/linuxthreads/sysdeps/pthread/bits/initspin.h	Wed Dec 31 19:00:00 1969
+++ glibc/linuxthreads/sysdeps/pthread/bits/initspin.h	Thu Oct 12 15:02:33 2000
@@ -0,0 +1,28 @@
+/* Generic definitions for spinlock initializers.
+   Copyright (C) 2000 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* Initial value of a spinlock.  Most platforms should use zero,
+   unless they only implement a "test and clear" operation instead of
+   the usual "test and set". */
+#define LT_SPINLOCK_INIT 0
+
+/* 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 --exclude=configure --exclude=.cvsignore --exclude=CVS --exclude=*.texi --exclude=texis --exclude=*.info* --exclude=*~ glibc-2.1.95/linuxthreads/sysdeps/pthread/bits/libc-lock.h glibc/linuxthreads/sysdeps/pthread/bits/libc-lock.h
--- glibc-2.1.95/linuxthreads/sysdeps/pthread/bits/libc-lock.h	Fri Jul  7 13:57:27 2000
+++ glibc/linuxthreads/sysdeps/pthread/bits/libc-lock.h	Thu Oct  5 14:59:08 2000
@@ -48,12 +48,21 @@
 
 /* Define an initialized lock variable NAME with storage class CLASS.
 
-   For the C library we take a deeper look at the initializer.  For this
-   implementation all fields are initialized to zero.  Therefore we
-   don't initialize the variable which allows putting it into the BSS
-   section.  */
-#define __libc_lock_define_initialized(CLASS,NAME) \
+   For the C library we take a deeper look at the initializer.  For
+   this implementation all fields are initialized to zero.  Therefore
+   we don't initialize the variable which allows putting it into the
+   BSS section.  (Except on PA-RISC and other odd architectures, where
+   initialized locks must be set to one due to the lack of normal
+   atomic operations.) */
+
+#if LT_SPINLOCK_INIT == 0
+#  define __libc_lock_define_initialized(CLASS,NAME) \
   CLASS __libc_lock_t NAME;
+#else
+#  define __libc_lock_define_initialized(CLASS,NAME) \
+  CLASS __libc_lock_t NAME = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
 #define __libc_rwlock_define_initialized(CLASS,NAME) \
   CLASS __libc_rwlock_t NAME = PTHREAD_RWLOCK_INITIALIZER;
 
@@ -143,9 +152,9 @@
   do {									      \
     if (__pthread_once != NULL)						      \
       __pthread_once (&(ONCE_CONTROL), (INIT_FUNCTION));		      \
-    else if ((ONCE_CONTROL) == 0) {					      \
+    else if ((ONCE_CONTROL) == PTHREAD_ONCE_INIT) {			      \
       INIT_FUNCTION ();							      \
-      (ONCE_CONTROL) = 1;						      \
+      (ONCE_CONTROL) = !PTHREAD_ONCE_INIT;				      \
     }									      \
   } while (0)
 
diff -urN --exclude=configure --exclude=.cvsignore --exclude=CVS --exclude=*.texi --exclude=texis --exclude=*.info* --exclude=*~ glibc-2.1.95/linuxthreads/sysdeps/pthread/pthread.h glibc/linuxthreads/sysdeps/pthread/pthread.h
--- glibc-2.1.95/linuxthreads/sysdeps/pthread/pthread.h	Thu Sep 14 15:24:17 2000
+++ glibc/linuxthreads/sysdeps/pthread/pthread.h	Thu Oct 12 15:31:57 2000
@@ -23,6 +23,7 @@
 #define __need_sigset_t
 #include <signal.h>
 #include <bits/pthreadtypes.h>
+#include <bits/initspin.h>
 
 
 __BEGIN_DECLS
@@ -30,26 +31,26 @@
 /* Initializers.  */
 
 #define PTHREAD_MUTEX_INITIALIZER \
-  {0, 0, 0, PTHREAD_MUTEX_TIMED_NP, {0, 0}}
+  {0, 0, 0, PTHREAD_MUTEX_TIMED_NP, LOCK_INITIALIZER}
 #ifdef __USE_GNU
 # define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
-  {0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, {0, 0}}
+  {0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, LOCK_INITIALIZER}
 # define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
-  {0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, {0, 0}}
+  {0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, LOCK_INITIALIZER}
 # define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
-  {0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, {0, 0}}
+  {0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, LOCK_INITIALIZER}
 #endif
 
-#define PTHREAD_COND_INITIALIZER {{0, 0}, 0}
+#define PTHREAD_COND_INITIALIZER {LOCK_INITIALIZER, 0}
 
 #ifdef __USE_UNIX98
 # define PTHREAD_RWLOCK_INITIALIZER \
-  { {0, 0}, 0, NULL, NULL, NULL,					      \
+  { LOCK_INITIALIZER, 0, NULL, NULL, NULL,					      \
     PTHREAD_RWLOCK_DEFAULT_NP, PTHREAD_PROCESS_PRIVATE }
 #endif
 #ifdef __USE_GNU
 # define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
-  { {0, 0}, 0, NULL, NULL, NULL,					      \
+  { LOCK_INITIALIZER, 0, NULL, NULL, NULL,					      \
     PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, PTHREAD_PROCESS_PRIVATE }
 #endif
 
diff -urN --exclude=configure --exclude=.cvsignore --exclude=CVS --exclude=*.texi --exclude=texis --exclude=*.info* --exclude=*~ glibc-2.1.95/sysdeps/unix/sysv/linux/Makefile glibc/sysdeps/unix/sysv/linux/Makefile
--- glibc-2.1.95/sysdeps/unix/sysv/linux/Makefile	Tue Mar 28 14:05:47 2000
+++ glibc/sysdeps/unix/sysv/linux/Makefile	Thu Oct  5 17:30:03 2000
@@ -86,7 +86,7 @@
 endif
 
 ifeq ($(subdir),posix)
-sysdep_headers += bits/pthreadtypes.h
+sysdep_headers += bits/pthreadtypes.h bits/initspin.h
 endif
 
 ifeq ($(subdir),inet)
diff -urN --exclude=configure --exclude=.cvsignore --exclude=CVS --exclude=*.texi --exclude=texis --exclude=*.info* --exclude=*~ glibc-2.1.95/sysdeps/unix/sysv/linux/bits/initspin.h glibc/sysdeps/unix/sysv/linux/bits/initspin.h
--- glibc-2.1.95/sysdeps/unix/sysv/linux/bits/initspin.h	Wed Dec 31 19:00:00 1969
+++ glibc/sysdeps/unix/sysv/linux/bits/initspin.h	Thu Oct  5 17:30:11 2000
@@ -0,0 +1 @@
+/* No thread support. */


-- 
dhd@linuxcare.com, http://www.linuxcare.com/
Linuxcare. Support for the revolution.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]