• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
how to test atomicity?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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
  • Follow-Ups:
    • Re: how to test atomicity?
      • From: "Sean McBride" <email@hidden>
    • Re: how to test atomicity?
      • From: Matt Watson <email@hidden>
  • Prev by Date: Re: Using MIG RPC between 2 threads inside a process
  • Next by Date: Re: how to test atomicity?
  • Previous by thread: unlink: invalid argument
  • Next by thread: Re: how to test atomicity?
  • Index(es):
    • Date
    • Thread