#include #include #include #include #include monitor global_t {}; global_t globalA; global_t globalB; global_t globalC; condition condAB, condAC, condBC, condABC; thread Signaler { int signals[4]; }; void ?{}( Signaler * this ){ this->signals[0] = 0; this->signals[1] = 0; this->signals[2] = 0; this->signals[3] = 0; } thread WaiterAB {}; thread WaiterAC {}; thread WaiterBC {}; thread WaiterABC{}; volatile bool done; //---------------------------------------------------------------------------------------------------- // Tools void signal( condition * cond, global_t * mutex a, global_t * mutex b ) { signal( cond ); } void signal( condition * cond, global_t * mutex a, global_t * mutex b, global_t * mutex c ) { signal( cond ); } void wait( condition * cond, global_t * mutex a, global_t * mutex b ) { wait( cond ); } void wait( condition * cond, global_t * mutex a, global_t * mutex b, global_t * mutex c ) { wait( cond ); } //---------------------------------------------------------------------------------------------------- // Signaler void main( Signaler* this ) { while( true ) { int action = (unsigned)rand48() % 4; bool finished = true; for(int i = 0; i < 4; i++) { if( this->signals[action] < 10_000 ) { finished = false; break; } else { action = (action + 1) % 4; } } this->signals[action]++; if( finished ) break; //sout | action | this->signals[0] | this->signals[1] | this->signals[2] | this->signals[3] | endl; switch( action ) { case 0: signal( &condABC, &globalA, &globalB, &globalC ); break; case 1: signal( &condAB , &globalA, &globalB ); break; case 2: signal( &condBC , &globalB, &globalC ); break; case 3: signal( &condAC , &globalA, &globalC ); break; default: sout | "Something went wrong" | endl; abort(); } } } //---------------------------------------------------------------------------------------------------- // Waiter ABC void main( WaiterABC* this ) { while( !done ) { wait( &condABC, &globalA, &globalB, &globalC ); } } //---------------------------------------------------------------------------------------------------- // Waiter AB void main( WaiterAB* this ) { while( !done ) { wait( &condAB , &globalA, &globalB ); } } //---------------------------------------------------------------------------------------------------- // Waiter AC void main( WaiterAC* this ) { while( !done ) { wait( &condAC , &globalA, &globalC ); } } //---------------------------------------------------------------------------------------------------- // Waiter BC void main( WaiterBC* this ) { while( !done ) { wait( &condBC , &globalB, &globalC ); } } //---------------------------------------------------------------------------------------------------- // Main int main(int argc, char* argv[]) { done = false; processor p; { WaiterABC a; WaiterAB b; WaiterBC c; WaiterAC d; { Signaler e; } done = true; signal( &condABC, &globalA, &globalB, &globalC ); signal( &condAB , &globalA, &globalB ); signal( &condBC , &globalB, &globalC ); signal( &condAC , &globalA, &globalC ); } }