#include <random>
#include <atomic>
#include <thread>
#include <iostream>
#include <exception>



int main ( void )
{try{
	int shared = 0;
	std::atomic<int> flag;
	
	std::random_device rd;
	std::default_random_engine el(rd());
	std::uniform_int_distribution<int> ud(1,10);

	auto f = [&flag, &shared, &el, &ud](){

	    int count = 0;
	    while (count < 10000000)
    	{
			volatile int busy_wait = ud(el)*100;
			for ( ; busy_wait; --busy_wait );
			
	        int expected = 0;
    	    if (flag.compare_exchange_strong(expected, 1, std::memory_order_relaxed))
        	{
	            // Lock was successful
    	        shared++;
        	    flag.store(0, std::memory_order_relaxed);
            	count++;
	        }
    	}	
	};

	std::thread t1( f );
	std::thread t2( f );

	t1.join();
	t2.join();

	std::cout << "shared = " << shared << std::endl;

	return 0;
}
catch ( const std::exception& e )
{
	std::cerr << std::endl
			<< "std::exception(\"" << e.what() << "\")." << std::endl;
	return 2;
}
catch ( ... )
{
	std::cerr  << std::endl
			<< "unknown exception." << std::endl;
	return 1;
}}

