#include #include #include #include #include static const unsigned N = 100_000; enum state_t { WAITED, SIGNAL, BARGE }; monitor global_t {}; monitor global_data_t { state_t state; bool ran; }; void ?{} ( global_data_t * this ) { this->state = BARGE; } void ^?{} ( global_data_t * this ) {} global_data_t globalA, globalB; condition cond; volatile bool done; //------------------------------------------------------------------------------ void wait_op( global_data_t * mutex a, global_data_t * mutex b, unsigned i ) { wait( &cond ); a->ran = b->ran = true; yield( ((unsigned)rand48()) % 10 ); if(a->state != SIGNAL || b->state != SIGNAL) { sout | "ERROR Barging detected" | a->state | b->state | endl; abort(); } a->state = b->state = WAITED; yield( ((unsigned)rand48()) % 10 ); } thread Waiter {}; void main( Waiter* this ) { for( int i = 0; i < N; i++ ) { wait_op( &globalA, &globalB, i ); } } //------------------------------------------------------------------------------ void signal_op( global_data_t * mutex a, global_data_t * mutex b ) { yield( ((unsigned)rand48()) % 10 ); a->ran = b->ran = false; a->state = b->state = SIGNAL; signal_block( &cond ); yield( ((unsigned)rand48()) % 10 ); assert(a->ran == b->ran); if(a->ran) { if(a->state != WAITED || b->state != WAITED) { sout | "ERROR Barging detected" | a->state | b->state | endl; abort(); } } } thread Signaller {}; void main( Signaller* this ) { while( !done ) { signal_op( &globalA, &globalB ); } } //------------------------------------------------------------------------------ void barge_op( global_data_t * mutex a ) { a->state = BARGE; } thread Barger {}; void main( Barger* this ) { for( unsigned i = 0; !done; i++ ) { //Choose some monitor to barge into with some irregular pattern bool choose_a = (i % 13) > (i % 17); barge_op( choose_a ? &globalA : &globalB ); } } //------------------------------------------------------------------------------ int main(int argc, char* argv[]) { rand48seed(0); done = false; processor p; { Signaller s[4]; Barger b[13]; sout | "Starting waiters" | endl; { Waiter w[3]; } sout | "Waiters done" | endl; done = true; } }