o no longer need to define OSD_ATOMIC_GCC

o removed function
epicsAtomicTestAndSetUIntT
o added new functions
epicsAtomicSetPtrT
epicsAtomicGetPtrT
epicsAtomicCmpAndSwapUIntT
epicsAtomicCmpAndSwapPtrT
o changed msvc intrinsics to define memory fence
o fixed mutex synchronized version so that its slow, but correct if the c++ compiler doesnt synchronized local scope static initialization
o changed most of the set/get methods to use memory barriers instead of some other primitive
o added additional tests
This commit is contained in:
Jeff Hill
2011-08-15 17:00:01 -06:00
committed by Andrew Johnson
parent c872c44668
commit bd1b1479f4
10 changed files with 525 additions and 266 deletions

View File

@@ -305,46 +305,46 @@ inline void oneThousandAtomicIncr ( size_t & target )
oneHundredAtomicIncr ( target );
}
inline void tenAtomicTestAndSet ( unsigned & target )
inline void tenAtomicCmpAndSwap ( unsigned & target )
{
epicsAtomicTestAndSetUIntT ( & target );
epicsAtomicTestAndSetUIntT ( & target );
epicsAtomicTestAndSetUIntT ( & target );
epicsAtomicTestAndSetUIntT ( & target );
epicsAtomicTestAndSetUIntT ( & target );
epicsAtomicTestAndSetUIntT ( & target );
epicsAtomicTestAndSetUIntT ( & target );
epicsAtomicTestAndSetUIntT ( & target );
epicsAtomicTestAndSetUIntT ( & target );
epicsAtomicTestAndSetUIntT ( & target );
epicsAtomicCmpAndSwapUIntT ( & target, false, true );
epicsAtomicCmpAndSwapUIntT ( & target, false, true );
epicsAtomicCmpAndSwapUIntT ( & target, false, true );
epicsAtomicCmpAndSwapUIntT ( & target, false, true );
epicsAtomicCmpAndSwapUIntT ( & target, false, true );
epicsAtomicCmpAndSwapUIntT ( & target, false, true );
epicsAtomicCmpAndSwapUIntT ( & target, false, true );
epicsAtomicCmpAndSwapUIntT ( & target, false, true );
epicsAtomicCmpAndSwapUIntT ( & target, false, true );
epicsAtomicCmpAndSwapUIntT ( & target, false, true );
}
inline void oneHundredAtomicTestAndSet ( unsigned & target )
inline void oneHundredAtomicCmpAndSwap ( unsigned & target )
{
tenAtomicTestAndSet ( target );
tenAtomicTestAndSet ( target );
tenAtomicTestAndSet ( target );
tenAtomicTestAndSet ( target );
tenAtomicTestAndSet ( target );
tenAtomicTestAndSet ( target );
tenAtomicTestAndSet ( target );
tenAtomicTestAndSet ( target );
tenAtomicTestAndSet ( target );
tenAtomicTestAndSet ( target );
tenAtomicCmpAndSwap ( target );
tenAtomicCmpAndSwap ( target );
tenAtomicCmpAndSwap ( target );
tenAtomicCmpAndSwap ( target );
tenAtomicCmpAndSwap ( target );
tenAtomicCmpAndSwap ( target );
tenAtomicCmpAndSwap ( target );
tenAtomicCmpAndSwap ( target );
tenAtomicCmpAndSwap ( target );
tenAtomicCmpAndSwap ( target );
}
inline void oneThousandAtomicTestAndSet ( unsigned & target )
inline void oneThousandAtomicCmpAndSwap ( unsigned & target )
{
oneHundredAtomicTestAndSet ( target );
oneHundredAtomicTestAndSet ( target );
oneHundredAtomicTestAndSet ( target );
oneHundredAtomicTestAndSet ( target );
oneHundredAtomicTestAndSet ( target );
oneHundredAtomicTestAndSet ( target );
oneHundredAtomicTestAndSet ( target );
oneHundredAtomicTestAndSet ( target );
oneHundredAtomicTestAndSet ( target );
oneHundredAtomicTestAndSet ( target );
oneHundredAtomicCmpAndSwap ( target );
oneHundredAtomicCmpAndSwap ( target );
oneHundredAtomicCmpAndSwap ( target );
oneHundredAtomicCmpAndSwap ( target );
oneHundredAtomicCmpAndSwap ( target );
oneHundredAtomicCmpAndSwap ( target );
oneHundredAtomicCmpAndSwap ( target );
oneHundredAtomicCmpAndSwap ( target );
oneHundredAtomicCmpAndSwap ( target );
oneHundredAtomicCmpAndSwap ( target );
}
inline void tenAtomicSet ( size_t & target )
@@ -421,20 +421,20 @@ void epicsAtomicIncrPerformance ()
testDiag ( "epicsAtomicIncr() takes %f microseconds", delay );
}
void atomicTestAndSetPerformance ()
void atomicCmpAndSwapPerformance ()
{
epicsTime begin = epicsTime::getCurrent ();
unsigned target;
epicsAtomicSetUIntT ( & target, 0 );
testOk1 ( ! target );
for ( unsigned i = 0; i < N; i++ ) {
oneThousandAtomicTestAndSet ( target );
oneThousandAtomicCmpAndSwap ( target );
}
double delay = epicsTime::getCurrent () - begin;
testOk1 ( target );
delay /= N * 1000u; // convert to delay per call
delay *= 1e6; // convert to micro seconds
testDiag ( "epicsAtomicCompareAndSet() takes %f microseconds", delay );
testDiag ( "epicsAtomicCmpAndSwap() takes %f microseconds", delay );
}
void recursiveOwnershipRetPerformance ()
@@ -494,6 +494,6 @@ MAIN(epicsAtomicPerform)
epicsAtomicIncrPerformance ();
recursiveOwnershipRetPerformance ();
ownershipPassRefPerformance ();
atomicCompareAndSetPerformance ();
atomicCmpAndSwapPerformance ();
return testDone();
}