#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: