[parisc-linux-cvs] gcc amodra

Alan Modra alan@linuxcare.com.au
Sat, 7 Apr 2001 20:57:02 +1000 (EST)


On Sat, 7 Apr 2001, Alan Modra wrote:

> Modified files:
> 	libstdc++-v3   : ChangeLog.puffin 
> 	libstdc++-v3/config/cpu/hppa/bits: atomicity.h 
> 	libstdc++-v3/include/bits: basic_string.h basic_string.tcc 
> 
> Log message:
> Fix C++ hangs since 2001-03-26 patch caused by locks not being
> initialised non-zero.

CVS c++ has been broken for quite a while.  This fixes it, I think.
I'd appreciate someone who knows c++ taking a look at it as I only
pretend to be a c++ programmer.

	* config/cpu/hppa/bits/atomicity.h: Another rewrite, this time
	making use of some c++ features.
	* include/bits/basic_string.h (_S_empty_rep_storage): Align to
	16 byte boundary.
	* include/bits/basic_string.tcc (_S_empty_rep_storage): Likewise.
	Init from _S_EMPTY_REP_INIT if defined.

Alan

Index: config/cpu/hppa/bits/atomicity.h
===================================================================
RCS file: /home/cvs/parisc/gcc/libstdc++-v3/config/cpu/hppa/bits/atomicity.h,v
retrieving revision 1.3
diff -u -p -r1.3 atomicity.h
--- atomicity.h	2001/03/27 01:55:46	1.3
+++ atomicity.h	2001/04/07 10:17:05
@@ -1,4 +1,4 @@
-/* Low-level functions for atomic operations.  PA-RISC version.
+/* Low-level functions for atomic operations.  PA-RISC version. -*- C++ -*-
    Copyright 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -20,14 +20,6 @@
 #ifndef _BITS_ATOMICITY_H
 #define _BITS_ATOMICITY_H	1
 
-typedef int _Atomic_word;
-
-#define	_ATOMIC_WORD_LOCK \
-int _pa_lock __attribute__ ((__aligned__ (16)));
-
-#define	_ATOMIC_WORD_LOCK_INIT \
-  _pa_lock = 1;
-
 /* Load and clear, the only PA-RISC atomic read-write operation.  Some
    cpus only support ldcw on 16 byte aligned words.  *sigh*.  */
 static inline int
@@ -47,38 +39,60 @@ __pa_spin_lock (volatile int* lock)
     while (*lock == 0) /* spin */ ;
   return ret;
 }
+
 
-#define __exchange_and_add(mem, val) \
-  __pa_exchange_and_add (&_pa_lock, mem, val)
+class _Atomic_counter {
+ public:
+  int lock __attribute__ ((__aligned__ (16)));
+  int count;
+
+  inline
+  _Atomic_counter() { lock = 1; }
+
+  inline int
+  operator=(const int __val) { return this->count = __val; }
+
+  inline bool
+  operator<(const int __rhs) const
+    { return this->count < __rhs; }
+
+  inline bool
+  operator>(const int __rhs) const
+    { return this->count > __rhs; }
+};
+
+typedef class _Atomic_counter _Atomic_word;
+
+/* This is horrible, but how else can we get the static initializer
+   correct with our lock set non-zero? */
+#define _S_EMPTY_REP_INIT = { 0, 0, 0, 0, 1, 0, 0, 0, 0 }
 
-#define __atomic_add(mem, val) \
-  __pa_atomic_add (&_pa_lock, mem, val)
 
 static inline int
 __attribute__ ((__unused__))
-__pa_exchange_and_add (int* lock, _Atomic_word* mem, int val)
+__exchange_and_add (_Atomic_word* mem, int val)
 {
-  _Atomic_word result;
+  int result;
   int tmp;
 
-  tmp = __pa_spin_lock (lock);
-  result = *mem;
-  *mem += val;
+  tmp = __pa_spin_lock (&mem->lock);
+  result = mem->count;
+  mem->count += val;
   __asm__ __volatile__("");
-  *lock = tmp;
+  mem->lock = tmp;
   return result;
 }
 
 static inline void
 __attribute__ ((__unused__))
-__pa_atomic_add (int* lock, _Atomic_word* mem, int val)
+__atomic_add (_Atomic_word* mem, int val)
 {
   int tmp;
 
-  tmp = __pa_spin_lock (lock);
-  *mem += val;
+  tmp = __pa_spin_lock (&mem->lock);
+  mem->count += val;
   __asm__ __volatile__("");
-  *lock = tmp;
+  mem->lock = tmp;
 }
 
-#endif /* atomicity.h */
+#endif
Index: include/bits/basic_string.h
===================================================================
RCS file: /home/cvs/parisc/gcc/libstdc++-v3/include/bits/basic_string.h,v
retrieving revision 1.5
diff -u -p -r1.5 basic_string.h
--- basic_string.h	2001/03/27 01:55:47	1.5
+++ basic_string.h	2001/04/07 10:17:11
@@ -138,9 +138,6 @@ namespace std {
 	size_type 		_M_length;
 	size_type 		_M_capacity;
 	_Atomic_word		_M_references;
-#ifdef _ATOMIC_WORD_LOCK
-	_ATOMIC_WORD_LOCK
-#endif
 
         bool
 	_M_is_leaked() const
@@ -156,12 +153,7 @@ namespace std {
 
         void
 	_M_set_sharable() 
-        {
-	  _M_references = 0;
-#ifdef _ATOMIC_WORD_LOCK_INIT
-	  _ATOMIC_WORD_LOCK_INIT
-#endif
-	}
+	{ _M_references = 0; }
 
 	_CharT* 
 	_M_refdata() throw()
@@ -238,7 +230,10 @@ namespace std {
 
       // The following storage is init'd to 0 by the linker, resulting
       // (carefully) in an empty string with one reference.
-      static size_type _S_empty_rep_storage[(sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)];
+      static size_type _S_empty_rep_storage[
+	(sizeof(_Rep) + sizeof(_CharT)
+	 + sizeof(size_type) - 1)/sizeof(size_type)]
+      __attribute__ ((__aligned__ (16)));
 
       _CharT* 
       _M_data() const 
Index: include/bits/basic_string.tcc
===================================================================
RCS file: /home/cvs/parisc/gcc/libstdc++-v3/include/bits/basic_string.tcc,v
retrieving revision 1.4
diff -u -p -r1.4 basic_string.tcc
--- basic_string.tcc	2001/03/23 04:26:42	1.4
+++ basic_string.tcc	2001/04/07 10:17:18
@@ -61,7 +61,12 @@ namespace std
   template<typename _CharT, typename _Traits, typename _Alloc>
     typename basic_string<_CharT, _Traits, _Alloc>::size_type
     basic_string<_CharT, _Traits, _Alloc>::_S_empty_rep_storage[
-    (sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)];
+    (sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)]
+    __attribute__ ((__aligned__ (16)))
+#ifdef _S_EMPTY_REP_INIT
+    _S_EMPTY_REP_INIT
+#endif
+  ;
 
   // NB: This is the special case for Input Iterators, used in
   // istreambuf_iterators, etc.