[parisc-linux-cvs] gcc amodra

Alan Modra alan@linuxcare.com.au
Mon, 9 Apr 2001 14:19:24 +1000 (EST)


On Sun, 8 Apr 2001, Alan Modra wrote:

> Log message:
> Yet more changes to make basic_strings MT safe.  The last try didn't
> work due to malloc anly aligning to 8 bytes.

A wee bit gross..  Perhaps a kernel atomic exchange_and_add would be a
godd idea?  willy?

	* config/cpu/hppa/bits/atomicity.h (_Atomic_counter): Use two
	locks to get around the problem of malloc only aligning to
	8 byte boundaries.  Remove alignment on lock so we don't
	unnecessarily allocate extra memory.
	(_S_EMPTY_REP_INIT): Update for above change.
	(__exchange_and_add): Mask lock address.
	(__atomic_add): Likewise.
	* include/bits/basic_string.h (_S_empty_rep_storage): Only align
	to 8 byte boundary.
	* include/bits/basic_string.tcc (_S_empty_rep_storage): Likewise.

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.4
diff -u -p -r1.4 atomicity.h
--- atomicity.h	2001/04/07 10:27:16	1.4
+++ atomicity.h	2001/04/09 04:05:37
@@ -43,11 +43,15 @@ __pa_spin_lock (volatile int* lock)
 
 class _Atomic_counter {
  public:
-  int lock __attribute__ ((__aligned__ (16)));
+  /* Two locks???  Well, malloc allocates to 8 byte boundaries, and
+     thus either lock or alt_lock will be 16 byte aligned.  Use
+     whichever one gets the right alignment.  */
+  int lock;
   int count;
+  int alt_lock;
 
   inline
-  _Atomic_counter() { lock = 1; }
+  _Atomic_counter() { lock = 1; alt_lock = 1; }
 
   inline int
   operator=(const int __val) { return this->count = __val; }
@@ -64,8 +68,8 @@ class _Atomic_counter {
 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 }
+   correct with our lock(s) set non-zero? */
+#define _S_EMPTY_REP_INIT = { 0, 0, 1, 0, 1, 0 }
 
 
 static inline int
@@ -74,12 +78,13 @@ __exchange_and_add (_Atomic_word* mem, i
 {
   int result;
   int tmp;
+  int *lock = (int *) ((long) &mem->alt_lock & ~15);
 
-  tmp = __pa_spin_lock (&mem->lock);
+  tmp = __pa_spin_lock (lock);
   result = mem->count;
   mem->count += val;
   __asm__ __volatile__("");
-  mem->lock = tmp;
+  *lock = tmp;
   return result;
 }
 
@@ -88,11 +93,12 @@ __attribute__ ((__unused__))
 __atomic_add (_Atomic_word* mem, int val)
 {
   int tmp;
+  int *lock = (int *) ((long) &mem->alt_lock & ~15);
 
-  tmp = __pa_spin_lock (&mem->lock);
+  tmp = __pa_spin_lock (lock);
   mem->count += val;
   __asm__ __volatile__("");
-  mem->lock = tmp;
+  *lock = tmp;
 }
 
 #endif
Index: include/bits/basic_string.h
===================================================================
RCS file: /home/cvs/parisc/gcc/libstdc++-v3/include/bits/basic_string.h,v
retrieving revision 1.6
diff -u -p -r1.6 basic_string.h
--- basic_string.h	2001/04/07 10:27:17	1.6
+++ basic_string.h	2001/04/09 04:05:43
@@ -233,7 +233,7 @@ namespace std {
       static size_type _S_empty_rep_storage[
 	(sizeof(_Rep) + sizeof(_CharT)
 	 + sizeof(size_type) - 1)/sizeof(size_type)]
-      __attribute__ ((__aligned__ (16)));
+      __attribute__ ((__aligned__ (8)));
 
       _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.5
diff -u -p -r1.5 basic_string.tcc
--- basic_string.tcc	2001/04/07 10:27:17	1.5
+++ basic_string.tcc	2001/04/09 04:05:47
@@ -62,7 +62,7 @@ namespace std
     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)]
-    __attribute__ ((__aligned__ (16)))
+    __attribute__ ((__aligned__ (8)))
 #ifdef _S_EMPTY_REP_INIT
     _S_EMPTY_REP_INIT
 #endif