[RFC] libstdc++ atomicity, x86 agnostic version

Jakub Jelinek jakub@redhat.com
Wed Feb 25 19:26:00 GMT 2004


On Wed, Feb 25, 2004 at 07:25:51PM +0100, Paolo Carlini wrote:
> Benjamin Kosnik wrote:
> 
> >I expect some comments about the fact that these atomic functions will
> >no longer be inlined, impacting performance. Therefore, I attach the a
> >performance testrun with the patch, which shows a minimal impact.
> >
> This seems really sad and more specific tests should be performed: the 
> current
> performance testsuite definitely is not tuned to benchmark that.

IMHO inlining the atomic ops is important for performance reasons.
But at least last time I briefly looked into this problem (in January)
it looked solvable to me (and I did something similar in the past for GCC
2.96-RH).

In current CVS, grep shows these uses of __exchange_and_add:

./src/ios_init.cc:    if (__exchange_and_add(&_S_refcount, 1) == 0)
./src/ios_init.cc:    if (__exchange_and_add(&_S_refcount, -1) == 2)
./src/ios.cc:    return __exchange_and_add(&_S_top, 1) + 4;
./src/locale.cc:      _M_index = 1 + __exchange_and_add(&_S_refcount, 1);
./include/bits/basic_string.h:      if (__exchange_and_add(&this->_M_refcount, -1) <= 0)
./include/bits/ios_base.h:      _M_remove_reference() { return __exchange_and_add(&_M_refcount, -1); }
./include/bits/locale_classes.h:      if (__exchange_and_add(&_M_refcount, -1) == 1)
./include/bits/locale_classes.h:      if (__exchange_and_add(&_M_refcount, -1) == 1)

__atomic_add can be done using "lock; addl" on i386.
__exchange_and_add cannot be implemented in a generic way on i386 without
using some other lock or table of locks, but some cases can be handled
specially:
__exchange_and_add(x, -1) == 1
can be done using
asm ("lock; subl $1, %1; sete %b0" : "=q" (__val), "+m" (*x)); __val == 1
Similarly,
__exchange_and_add(x, -1) <= 0
is
asm ("lock; subl $1, %1; setl %b0" : "=q" (__val), "+m" (*x)); __val == 1

The *.cc files above are linked into libstdc++.{so,a}, so what exactly they
use is private to the implementation.
The only question is _M_remove_reference in ios_base.h.
The command above it says:
// 0 => OK to delete.
If the return value is only tested for == 0 or != 0, then this can be
handled on i386 as well.
The 4 above headers would just need to use specialized inlines or macros, which
on most platforms would be just __exchange_and_add with special arguments
but on IA-32 for -march=i386 compiles it would be different.
The installed atomicity.h header would just have
#if defined __i486__ || defined __i586__ || defined __i686__
define inlines using xaddl
#else
use above stuff
#endif
and use the same _Atomic_Word like current i486 atomicity.h header.
It would be binary compatible with the i486 implementation even on i386.

	Jakub



More information about the Libstdc++ mailing list