how to test atomicity?
how to test atomicity?
- Subject: how to test atomicity?
- From: email@hidden
- Date: Sun, 19 Sep 2004 08:22:55 -0700
Hello, all ...
I'm porting a class library / framework to OSX 10.3 / Darwin PPC. One
of the things needed is atomic increments, decrements and swaps. With
the help of others here, and various web sites, I found the lwarx /
stwcx pair and some assembly doing exactly what I want. Cool!
Now, the hard part -- I want to test these atomic incs / decs against
their non-atomic counterparts. I have a 12" PowerBook G4 and a dual-G4
desktop, so I can test atomic ops on both (esp. the dual G4). I wrote
some C++ code to launch 500 pthreads, half doing increments, the other
half doing decrements, on the same variable. Each thread does it's
thing a certain # of times, and if the incs and decs are atomic, the
variable should be the same when the test ends as when it started.
... at least, this is what i'm thinking. The problem is that my test
passes even w/o using the atomic inc / decs. I was hoping to see the
atomic version pass and the non-atomic version fail, but noooo. The
code (not much at all, actually) follows. Either I don't understand
the problem (I think I grok it pretty well), my code is not really
testing it (maybe), or the compiler (Apple's gcc3.3) is too smart for
me and laughs heartily at my pathetic and weak attempts to subvert it.
Can anyone tell me which of the above is true?
#include <pthread.h>
#include <iostream>
using namespace std;
typedef int AtomicCountType;
inline static AtomicCountType AtomicIncrement( volatile AtomicCountType
*p )
{
int tmp;
// code lifted from linux
asm volatile(
"1: lwarx %0,0,%1\n"
" addic %0,%0,1\n" // addic allows r0, addi
doesn't
" stwcx. %0,0,%1\n"
" bne- 1b"
: "=&r" (tmp)
: "r" ( p )
: "cc", "memory");
return( tmp );
}
inline static AtomicCountType AtomicDecrement( volatile AtomicCountType
*p )
{
int tmp;
// code lifted from linux
asm volatile(
"2: lwarx %0,0,%1\n"
" addic %0,%0,-1\n" // addic allows r0, addi
doesn't
" stwcx. %0,0,%1\n"
" bne- 2b"
: "=&r" (tmp)
: "r" ( p )
: "cc", "memory");
return( tmp );
}
inline static AtomicCountType AtomicBump( volatile AtomicCountType *p,
AtomicCountType AddMe )
{
int tmp;
// code lifted from linux
asm volatile(
"3: lwarx %0,0,%1\n"
" addic %0,%0,( AddMe )\n" // addic allows r0,
addi doesn't
" stwcx. %0,0,%1\n"
" bne- 3b"
: "=&r" (tmp)
: "r" ( p )
: "cc", "memory");
return( tmp );
}
void test_atomic_inc( void *pX )
{
int *piX = static_cast< int * >( pX );
for ( int iIndex = 0; iIndex < 1000000000; iIndex ++ )
{
//AtomicIncrement( piX );
( *piX ) ++;
}
pthread_exit( 0 );
}
void test_atomic_dec( void *pX )
{
int *piX = static_cast< int * >( pX );
for ( int iIndex = 0; iIndex < 1000000000; iIndex ++ )
{
//AtomicDecrement( piX );
( *piX ) --;
}
pthread_exit( 0 );
}
int main( int iArgc, char *pcArgv[] )
{
// our one true int ...
int iX = 0;
// ... and some other stuff
int iStatus = 0;
// create 500 threads, half doing incs, half doing decs
pthread_t threads[ 500 ] = { 0 };
for ( int iIndex = 0; iIndex < 500; iIndex ++ )
{
int iCreatedOK = pthread_create( &threads[ iIndex ],
NULL,
iIndex % 2 == 0 ?
test_atomic_inc : test_atomic_dec,
&iX );
if ( iCreatedOK != 0 )
{
cout << "can't make thread " << iIndex << "\n";
break;
}
else
{
pthread_join( threads[ iIndex ], ( void ** )&iStatus );
}
}
// test to make sure iX is still 0 i.e. operations were really
atomic
cout << "test " << ( iX == 0 ? "passed: " : "failed: " ) << iX <<
"\n";
pthread_exit( 0 );
}
Regards,
John
Falling You - exploring the beauty of voice and sound
New album, "Touch", available now
http://www.magnatune.com/artists/falling_you
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden