This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: libstdc++/5037: Multithreaded read access to strings notthreadsafe on Solaris/Sparc
- From: Loren James Rittle <rittle at latour dot rsch dot comm dot mot dot com>
- To: libstdc++ at gcc dot gnu dot org
- Date: Fri, 7 Dec 2001 15:03:15 -0600 (CST)
- Subject: Re: libstdc++/5037: Multithreaded read access to strings notthreadsafe on Solaris/Sparc
- Reply-to: rittle at labs dot mot dot com
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");
}