#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; } enum state_t { WAIT, SIGNAL, BARGE }; monitor global_t {}; global_t mut; monitor global_data_t; void ?{}( global_data_t & this ); void ^?{} ( global_data_t & this ); monitor global_data_t { int counter; state_t state; } data; condition cond; volatile bool all_done; void ?{}( global_data_t & this ) { this.counter == 0; this.state = BARGE; } void ^?{} ( global_data_t & this ) {} //------------------------------------------------------------------------------ // Barging logic void barge( global_data_t & mutex d ) { d.state = BARGE; } thread Barger {}; void main( Barger & this ) { while( !all_done ) { barge( data ); yield(); } } //------------------------------------------------------------------------------ // Waiting logic bool wait( global_t & mutex m, global_data_t & mutex d ) { wait( &cond ); if( d.state != SIGNAL ) { sout | "ERROR barging!" | endl; } d.counter++; if( (d.counter % 1000) == 0 ) sout | d.counter | endl; return d.counter < N; } thread Waiter {}; void main( Waiter & this ) { while( wait( mut, data ) ) { yield(); } } //------------------------------------------------------------------------------ // Signalling logic void signal( condition * cond, global_t & mutex a, global_data_t & mutex b ) { b.state = SIGNAL; signal( cond ); } void logic( global_t & mutex a ) { signal( &cond, a, data ); yield( (unsigned)rand48() % 10 ); //This is technically a mutual exclusion violation but the mutex monitor protects us bool running = data.counter < N && data.counter > 0; if( data.state != SIGNAL && running ) { sout | "ERROR Eager signal" | data.state | endl; } } thread Signaller {}; void main( Signaller & this ) { while( !all_done ) { logic( mut ); yield(); } } //------------------------------------------------------------------------------ // Main loop int main(int argc, char* argv[]) { rand48seed( time( NULL ) ); all_done = false; processor p; { Signaller s; Barger b[17]; { Waiter w[4]; } sout | "All waiter done" | endl; all_done = true; } }