Hi.

There is a test program I would to be explained to me:

*** BEGIN OF TEST PROGRAM ***
#include <stdio.h>
#include <boost/thread.hpp>

#define USE_SPINLOCKS
//#define USE_MUTEXES

boost::thread th1;
boost::thread th2;

boost::mutex mutex;

int global_int = 0;

bool IsNotEven(int code)
{
        boost::mutex::scoped_lock locker(mutex);
        bool ret = (code & 1);
        return ret;
}

void thread_func()
{
        for(int i = 0; i < 1000000; ++i)
        {
#ifdef USE_MUTEXES
                if(IsNotEven(global_int)) // (1)
#elif defined USE_SPINLOCKS
                if(__sync_fetch_and_and(&global_int, 1)) // (2)
#else
                ERROR__WRONG_COMPILED;
#endif
                        global_int+=9;
                else
                        global_int+=1;
        }
}

int main()
{
        th1 = boost::thread(&thread_func);
        th2 = boost::thread(&thread_func);
        th1.join();
        th2.join();
        printf("global_int = %d\n", global_int);
      
        return 0;
}
*** END OF TEST PROGRAM ***

Results of test program:

1) Test program compiled with USE_SPINLOCKS.
Outputs are always:
"global_int = 10"
"global_int = 10"
"global_int = 10"

2) Test program compiled with USE_MUTEXES.
Outputs differ from each other:
"global_int = 10000008"
"global_int = 10000000"
"global_int = 9763210"

Could you explain me why outputs produced with USE_SPINLOCKS compilation differ from USE_MUTEXES ones?
And what is the difference between (1) and (2) lines?

Best,
Andrew.

P.S.: I use guest Ubuntu-8.04 installed on VirtualBox. Host OS = Vista.