#include <iostream>
#include <ace/OS.h>
#include <ace/Thread_Manager.h>
#include <ace/Thread_Mutex.h>
#include <ace/Condition_T.h>
#include <ace/Guard_T.h>
typedef ACE_Condition< ACE_Thread_Mutex > Condition;
typedef ACE_Guard< ACE_Thread_Mutex > Guard;
typedef int Color;
const Color BLUE = 0;
const Color RED = 1;
const Color YELLOW = 2;
const Color FADED = 3;
struct MeetingPlace
{
int remaining_;
ACE_Thread_Mutex lock_;
Condition meetplaceAvailable_;
Condition meetCompleted_;
int creaturesInside_;
Color * swappedColor_;
MeetingPlace()
: remaining_( 10 )
, meetplaceAvailable_( lock_ )
, meetCompleted_( lock_ )
, creaturesInside_( 0 )
, swappedColor_( 0 )
{}
};
class Creature
{
public :
Creature(
Color my,
MeetingPlace & meetingPlace )
: my_( my )
, meetingPlace_( meetingPlace )
, creaturesMeet_( 0 )
{}
void
run()
{
while( true )
{
Color other = my_;
{
Guard localLock( meetingPlace_.lock_ );
while( meetingPlace_.creaturesInside_ >= 2 )
meetingPlace_.meetplaceAvailable_.wait();
if( meetingPlace_.remaining_ )
{
if( !meetingPlace_.swappedColor_ )
{
meetingPlace_.creaturesInside_ += 1;
meetingPlace_.swappedColor_ = &other;
meetingPlace_.meetCompleted_.wait();
meetingPlace_.swappedColor_ = 0;
meetingPlace_.creaturesInside_ = 0;
--meetingPlace_.remaining_;
meetingPlace_.meetplaceAvailable_.broadcast();
}
else
{
meetingPlace_.creaturesInside_ += 1;
other = *meetingPlace_.swappedColor_;
*meetingPlace_.swappedColor_ = my_;
meetingPlace_.meetCompleted_.signal();
}
}
else
break;
}
if( FADED != other )
{
my_ = complement( other );
++creaturesMeet_;
}
}
}
int
total() const
{
return creaturesMeet_;
}
private :
Color my_;
MeetingPlace & meetingPlace_;
int creaturesMeet_;
Color
complement( Color other ) const
{
switch( my_ )
{
case BLUE:
return other == RED ? YELLOW : RED;
case RED:
return other == BLUE ? YELLOW : BLUE;
case YELLOW:
return other == BLUE ? RED : BLUE;
default:
break;
}
return my_;
}
};
ACE_THR_FUNC_RETURN
creatureThread( void * arg )
{
Creature * creature = reinterpret_cast< Creature * >( arg );
creature->run();
return 0;
}
int
main( int argc, char ** argv )
{
MeetingPlace meetingPlace;
if( 2 == argc )
meetingPlace.remaining_ = ACE_OS::atoi( argv[ 1 ] );
const int creatureCount = 4;
Color colors[ creatureCount ] = { BLUE, RED, YELLOW, BLUE };
Creature * group[ creatureCount ];
int i;
for( i = 0; i != creatureCount; ++i )
{
group[ i ] = new Creature( colors[ i ], meetingPlace );
ACE_Thread_Manager::instance()->spawn(
&creatureThread, group[ i ] );
}
ACE_Thread_Manager::instance()->wait();
int total = 0;
for( i = 0; i != creatureCount; ++i )
{
total += group[ i ]->total();
delete group[ i ];
}
std::cout << total << std::endl;
return 0;
}
// vim:ts=2:sts=2:sw=2:expandtab:fenc=utf-8: