diff options
author | Ulrich Drepper <drepper@gcc.gnu.org> | 1999-05-07 10:16:09 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@gcc.gnu.org> | 1999-05-07 10:16:09 +0000 |
commit | 4ff8ec301f153b35f0bd6229344b59e131cdd06b (patch) | |
tree | 67c931fedbc81397924fffc01bd713931f0517e9 | |
parent | 199343c5914ef2bda2a4c6a4932a768ef9591bc7 (diff) | |
download | gcc-4ff8ec301f153b35f0bd6229344b59e131cdd06b.zip gcc-4ff8ec301f153b35f0bd6229344b59e131cdd06b.tar.gz gcc-4ff8ec301f153b35f0bd6229344b59e131cdd06b.tar.bz2 |
(class basic_string::Rep): Make release member function thread-safe for
ix86 (x>=4) and UltraSPARC.
From-SVN: r26820
-rw-r--r-- | libstdc++/std/bastring.h | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/libstdc++/std/bastring.h b/libstdc++/std/bastring.h index f188628..6206713 100644 --- a/libstdc++/std/bastring.h +++ b/libstdc++/std/bastring.h @@ -73,7 +73,34 @@ private: charT* data () { return reinterpret_cast<charT *>(this + 1); } charT& operator[] (size_t s) { return data () [s]; } charT* grab () { if (selfish) return clone (); ++ref; return data (); } +#if defined __i486__ || defined __i586__ || defined __i686__ + void release () + { + size_t __val; + asm ("lock; xaddl %0, %2" + : "=r" (__val) : "0" (-1), "m" (ref) : "memory"); + if (__val == 1) + delete this; + } +#elif defined __sparcv9__ + void release () + { + size_t __newval, __oldval = ref; + do + { + __newval = __oldval - 1; + __asm__ ("cas [%4], %2, %0" + : "=r" (__oldval), "=m" (ref) + : "r" (__oldval), "m" (ref), "r"(&(ref)), "0" (__newval)); + } + while (__newval != __oldval); + + if (__oldval == 0) + delete this; + } +#else void release () { if (--ref == 0) delete this; } +#endif inline static void * operator new (size_t, size_t); inline static void operator delete (void *); |