#include using namespace std; #include size_t Clients = 2, Time = 10; size_t globalTotal = 0; Future_ISM A, B, C; volatile bool server_done_loop = false; volatile bool client_done_loop = false; volatile bool client_done = false; volatile bool server_done = false; volatile size_t client_count = 0; volatile size_t client_loop_count = 0; _Task Client { void main() { size_t i = 0; for(;; i++ ) { _Select( A ) { A(); } and _Select( B ) { B(); } or _Select( C ) { C(); } // needs to check after waituntil for termination synchronization if ( client_done ) break; // Barrier-like synch needed to reset futures safely if ( __atomic_add_fetch(&client_count, 1, __ATOMIC_SEQ_CST) == Clients ) { client_count = 0; A.reset(); B.reset(); C.reset(); client_done_loop = true; } while( !client_done_loop ) {} // client barrier if ( __atomic_add_fetch( &client_loop_count, 1, __ATOMIC_SEQ_CST ) == Clients ) { client_done_loop = false; // reset barrier before clients can proceed past waituntil server_done_loop = true; // unblock server to restart iteration client_loop_count = 0; } } __atomic_fetch_add( &globalTotal, i, __ATOMIC_SEQ_CST ); } }; _Task Server { void main() { for( size_t i = 0; !server_done; i++ ) { if ( i % 4 == 0 ) { A.delivery(i); B.delivery(i); } else if ( i % 4 == 1 ) { A.delivery(i); C.delivery(i); } else if ( i % 4 == 2 ) { B.delivery(i); C.delivery(i); } else { C.delivery(i); } while( !server_done_loop && !server_done ) {} // server barrier server_done_loop = false; // reset server barrier } } }; int main( int argc, char * argv[] ) { switch ( argc ) { case 3: if ( strcmp( argv[2], "d" ) != 0 ) { // default ? Time = atoi( argv[2] ); } // if case 2: if ( strcmp( argv[1], "d" ) != 0 ) { // default ? Clients = atoi( argv[1] ); if ( Clients < 1 ) goto Usage; } // if case 1: // use defaults break; default: Usage: cerr << "Usage: " << argv[0] << " [ clients (> 0) | 'd' (default " << Clients << ") ] [ time (>= 0) | 'd' (default " << Time << ") ]" ; exit( EXIT_FAILURE ); } // switch uProcessor p[Clients]; { Client c[Clients]; { Server s; uBaseTask::sleep( uDuration( Time ) ); server_done = true; } while( A.available() || B.available() || C.available() ) {} client_done = true; C.delivery(1); // can't deliver 0 since it causes ambiguity } cout << globalTotal << endl; } // main