libstdc++/5037: Multithreaded read access to strings not threadsafe on Solaris/Sparc

Nathan Myers ncm-nospam@cantrip.org
Thu Dec 6 17:05:00 GMT 2001


On Thu, Dec 06, 2001 at 06:33:32PM -0600, Loren James Rittle wrote:
> > I believe this file [libstdc++-v3/config/cpu/sparc/*/bits/atomicity.h]
> > is broken.  __exchange_and_add and __atomic_add use separate locks,
> > and so are not protected from each other.

> Any best solution (in terms of contention) requires a locking word
> related to the first argument.  Would a designer of the atomicity.h
> abstraction layer prefer to provide such a solution?

This code was extracted from glibc-2.0.  Maybe they have already
fixed it there.  (If so, thanks a lot for the heads-up, guys.)

Here's a diff (untested) that relies on traditional linker behavior
to define the global object somewhere all by itself.

Somebody should look at the other atomicity.h files and see if there
are any more of these. 

Nathan Myers
ncm at cantrip dot org

*** old/libstdc++-v3/config/cpu/sparc/sparc32/bits/atomicity.h	Thu Dec  6 15:47:27 2001
--- gcc/libstdc++-v3/config/cpu/sparc/sparc32/bits/atomicity.h	Thu Dec  6 15:52:33 2001
***************
*** 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,43 ----
  
  typedef int _Atomic_word;
  
+ extern unsigned char  _S_atomicity_lock;
+ 
  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;
  }
--- 45,57 ----
  		       "	bne	1b\n\t"
  		       "	 nop"
  		       : "=&r" (__tmp)
! 		       : "r" (&_S_atomicity_lock)
  		       : "memory");
    __result = *__mem;
    *__mem += __val;
    __asm__ __volatile__("stb	%%g0, [%0]"
  		       : /* no outputs */
! 		       : "r" (&_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"
--- 60,65 ----
***************
*** 67,78 ****
  		       "	bne	1b\n\t"
  		       "	 nop"
  		       : "=&r" (__tmp)
! 		       : "r" (&__lock)
  		       : "memory");
    *__mem += __val;
    __asm__ __volatile__("stb	%%g0, [%0]"
  		       : /* no outputs */
! 		       : "r" (&__lock)
  		       : "memory");
  }
  
--- 67,78 ----
  		       "	bne	1b\n\t"
  		       "	 nop"
  		       : "=&r" (__tmp)
! 		       : "r" (&_S_atomicity_lock)
  		       : "memory");
    *__mem += __val;
    __asm__ __volatile__("stb	%%g0, [%0]"
  		       : /* no outputs */
! 		       : "r" (&_S_atomicity_lock)
  		       : "memory");
  }
  



More information about the Libstdc++ mailing list