#include #include #include #include #include static const unsigned long N = 10_000ul; #ifndef PREEMPTION_RATE #define PREEMPTION_RATE 10_000ul #endif unsigned int default_preemption() { return PREEMPTION_RATE; } monitor global_t {}; global_t globalA; global_t globalB; global_t globalC; condition condAB, condAC, condBC, condABC; thread Signaler {}; thread WaiterAB {}; thread WaiterAC {}; thread WaiterBC {}; thread WaiterABC{}; volatile int waiter_left; //---------------------------------------------------------------------------------------------------- // 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( waiter_left != 0 ) { unsigned action = (unsigned)rand48() % 4; 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(); } yield(); } } //---------------------------------------------------------------------------------------------------- // Waiter ABC void main( WaiterABC* this ) { for( int i = 0; i < N; i++ ) { wait( &condABC, &globalA, &globalB, &globalC ); } __sync_fetch_and_sub_4( &waiter_left, 1); } //---------------------------------------------------------------------------------------------------- // Waiter AB void main( WaiterAB* this ) { for( int i = 0; i < N; i++ ) { wait( &condAB , &globalA, &globalB ); } __sync_fetch_and_sub_4( &waiter_left, 1); } //---------------------------------------------------------------------------------------------------- // Waiter AC void main( WaiterAC* this ) { for( int i = 0; i < N; i++ ) { wait( &condAC , &globalA, &globalC ); } __sync_fetch_and_sub_4( &waiter_left, 1); } //---------------------------------------------------------------------------------------------------- // Waiter BC void main( WaiterBC* this ) { for( int i = 0; i < N; i++ ) { wait( &condBC , &globalB, &globalC ); } __sync_fetch_and_sub_4( &waiter_left, 1); } //---------------------------------------------------------------------------------------------------- // Main int main(int argc, char* argv[]) { waiter_left = 4; processor p[2]; sout | "Starting" | endl; { Signaler e; { WaiterABC a; WaiterAB b; WaiterBC c; WaiterAC d; } } sout | "Done" | endl; }