import tango.core.Thread; import tango.util.locks.Barrier; import tango.util.locks.Condition; import tango.util.locks.Mutex; import tango.util.locks.Semaphore; import tango.text.convert.Integer; import tango.io.Stdout; typedef int Color; const Color BLUE = 0, RED = 1, YELLOW = 2, FADED = 3; void main( char[][] args ) { int remaining = ( 2 == args.length ? parse( args[ 1 ], 10 ) : 10 ); auto meetplaceSem = new Semaphore( 2 ); auto meetplaceLock = new Mutex; auto meetCompleted = new Condition( meetplaceLock ); Color * swappedColor = null; auto group = new ThreadGroup; auto creatureStartBarrier = new Barrier( 2 ); int total = 0; foreach( c; [ BLUE, RED, YELLOW, BLUE ] ) { auto creature = new Thread( { auto my = c; int creaturesMeet = 0; creatureStartBarrier.wait; Color processMeeting() { Color other = my; meetplaceSem.acquire; scope localLock = new ScopedLock( meetplaceLock ); if( !swappedColor ) { if( remaining ) { swappedColor = &other; meetCompleted.wait(); swappedColor = null; --remaining; meetplaceSem.release; } else other = FADED; meetplaceSem.release; } else { other = *swappedColor; *swappedColor = my; meetCompleted.notify(); } return other; } Color complement( Color other ) { 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; } while( FADED != my ) { Color other = processMeeting; if( FADED != other ) { my = complement( other ); ++creaturesMeet; } else my = FADED; } Stdout( "creaturesMeet: " )( creaturesMeet ).newline; synchronized total += creaturesMeet; } ); creature.start; group.add( creature ); creatureStartBarrier.wait; } group.joinAll; Stdout( total ).newline; } // vim:ts=2:sts=2:sw=2:expandtab:fenc=utf-8: