This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [Patch] Use __GCC_HAVE_SYNC_COMPARE_AND_SWAP_*
Paolo Carlini wrote:
Peter Dimov wrote:
I see. In fact, as you may remember, I have been asking for an
infrastructure providing an emulation layer transparent to the users
for *years*...
I understand, but isn't the infrastructure now almost in place? The
compiler support is present; is it not just the library support that
is missing?
I wish I could share your optimism :-) These issues are nasty, very
nasty, given all the requirements. Please have a look to the past
exchanges on the lists: people came to the conclusion that the only
satisfactory and complete solution are multilibs. And that would not
solve the statically linked case. Well, if you have a complete
solution ready fullfilling all those requirements, just post it ;)
OK, here's what I have in mind. The basic assumption is that all targets
support a spinlock using __sync_lock_* or equivalent. I'll concentrate on
the 386 case here and fetch_and_add but the others are similar.
Assume a spinlock pool:
spinlock_t spinlocks[ 41 ];
spinlock_t spinlock_for( void * p )
{
return spinlocks[ (unsigned)p % 41 ];
}
void lock_spinlock_for( void * p );
void unlock_spinlock_for( void * p ); // omitted for brevity
// set by runtime at startup before any other code is executed
extern bool __is_486;
// emulation layer
int __sync_fetch_and_add_4( int * ptr, int value )
{
if( __is_486 )
{
asm { xadd [ptr], value } // pseudocode
}
else
{
lock_spinlock_for( ptr );
int r = *ptr; *ptr += value;
unlock_spinlock_for( ptr );
return r;
}
}
This seems to work as intended for all cases that come to mind. If a module
compiled with -m486 is linked with a module compiled with -m386, the result
will work when run on 486 or better since the emulation will have the same
effect as the inlined intrinsic.
I may of course be missing something; apologies if so.