#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; } }