This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: libstdc++/5037: Multithreaded read access to strings notthreadsafe on Solaris/Sparc


Nathan, et. al:

Here is a version of your patch that builds (libstdc++-v3 cleaned
before rebuild in already bootstrapped tree), links and passes the
test case of 5037 on a multiprocessor sparc.  Unless you veto it, I
will install it on mainline and then lobby Mark for it to be moved to
3.0.X branch before the 3.0.3 release.

Obviously, this solution is not portable back to plain C.  That is a
loss but I don't envy having to change the build process just to add
an instantiation step (much harder to get that patch on 3.0.X branch).
BTW, some raw high-level data taken against the test case of 5037
(which may or may not be at all representative):

[With the technique from your patch with my tweak:]

S rittle@magoo; psrinfo -v
  The sparcv9 processor [0, on-line] operates at 248 MHz,
S rittle@magoo; ./a.out
   213r    79.9u    33.1s       ./a.out
   142r    25.6u    15.0s       ./a.out # built with -O2

S rittle@ss137; psrinfo -v
  The sparc processor [0, on-line] operates at 125 MHz,
  The sparc processor [2, on-line] operates at 125 MHz,
S rittle@ss137; ./a.out
   398r   340.7u   139.3s       ./a.out
   259r   171.6u    92.6s       ./a.out # built with -O2

S rittle@ss137; psradm -f 2  # take processor 2 off-line
S rittle@ss137; ./a.out
   434r   217.0u   109.2s       ./a.out

[With my first patch:]

S rittle@magoo; ./a.out
   213r    77.5u    35.6s       ./a.out

S rittle@ss137; ./a.out # processor 2 put back on-line
   413r   336.1u   152.0s       ./a.out

(I didn't bother testing with one slower processor off-line.)

The test case has three threads with one creator thread and two
consumer threads.  Since the creator thread does far more work than
the two identical consumer threads, I would not expect linear speedup
with this test case as it is written.

Nathan Myers  <ncm@cantrip.org>
Loren Rittle <ljrittle@acm.org>

	libstdc++/5037
	* config/cpu/sparc/sparc32/bits/atomicity.h
	(struct __Atomicity_lock<__inst>): Add.
	(__Atomicity_lock<__inst>::_S_atomicity_lock): Add.
	(__exchange_and_add): Use __Atomicity_lock<0>::_S_atomicity_lock
	instead of lock local to static function.
	(__atomic_add): Likewise.

Index: libstdc++-v3/config/cpu/sparc/sparc32/bits/atomicity.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/config/cpu/sparc/sparc32/bits/atomicity.h,v
retrieving revision 1.2.6.1
diff -c -r1.2.6.1 atomicity.h
*** atomicity.h	2001/02/28 00:04:10	1.2.6.1
--- atomicity.h	2001/12/07 19:48:14
***************
*** 32,42 ****
  
  typedef int _Atomic_word;
  
  static int
  __attribute__ ((__unused__))
  __exchange_and_add (volatile _Atomic_word* __mem, int __val)
  {
-   static unsigned char __lock;
    _Atomic_word __result, __tmp;
  
    __asm__ __volatile__("1:	ldstub	[%1], %0\n\t"
--- 32,50 ----
  
  typedef int _Atomic_word;
  
+ template <int __inst>
+ struct __Atomicity_lock
+ {
+   static unsigned char _S_atomicity_lock;
+ };
+ 
+ template <int __inst>
+ unsigned char __Atomicity_lock<__inst>::_S_atomicity_lock = 0;
+ 
  static int
  __attribute__ ((__unused__))
  __exchange_and_add (volatile _Atomic_word* __mem, int __val)
  {
    _Atomic_word __result, __tmp;
  
    __asm__ __volatile__("1:	ldstub	[%1], %0\n\t"
***************
*** 44,56 ****
  		       "	bne	1b\n\t"
  		       "	 nop"
  		       : "=&r" (__tmp)
! 		       : "r" (&__lock)
  		       : "memory");
    __result = *__mem;
    *__mem += __val;
    __asm__ __volatile__("stb	%%g0, [%0]"
  		       : /* no outputs */
! 		       : "r" (&__lock)
  		       : "memory");
    return __result;
  }
--- 52,64 ----
  		       "	bne	1b\n\t"
  		       "	 nop"
  		       : "=&r" (__tmp)
! 		       : "r" (&__Atomicity_lock<0>::_S_atomicity_lock)
  		       : "memory");
    __result = *__mem;
    *__mem += __val;
    __asm__ __volatile__("stb	%%g0, [%0]"
  		       : /* no outputs */
! 		       : "r" (&__Atomicity_lock<0>::_S_atomicity_lock)
  		       : "memory");
    return __result;
  }
***************
*** 59,65 ****
  __attribute__ ((__unused__))
  __atomic_add (volatile _Atomic_word* __mem, int __val)
  {
-   static unsigned char __lock;
    _Atomic_word __tmp;
  
    __asm__ __volatile__("1:	ldstub	[%1], %0\n\t"
--- 67,72 ----
***************
*** 67,78 ****
  		       "	bne	1b\n\t"
  		       "	 nop"
  		       : "=&r" (__tmp)
! 		       : "r" (&__lock)
  		       : "memory");
    *__mem += __val;
    __asm__ __volatile__("stb	%%g0, [%0]"
  		       : /* no outputs */
! 		       : "r" (&__lock)
  		       : "memory");
  }
  
--- 74,85 ----
  		       "	bne	1b\n\t"
  		       "	 nop"
  		       : "=&r" (__tmp)
! 		       : "r" (&__Atomicity_lock<0>::_S_atomicity_lock)
  		       : "memory");
    *__mem += __val;
    __asm__ __volatile__("stb	%%g0, [%0]"
  		       : /* no outputs */
! 		       : "r" (&__Atomicity_lock<0>::_S_atomicity_lock)
  		       : "memory");
  }
  


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