#include #include #include #include #include #include #include size_t Clients = 1, Time = 10; size_t globalTotal = 0; future(size_t) 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; thread Client {}; void main( Client & this ) { size_t i = 0; for(;; i++ ) { waituntil( A ) { get(A); } and waituntil( B ) { get(B); } or waituntil( C ) { get(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 ) { // synchronize reset client_count = 0; reset( A ); reset( B ); reset( C ); client_done_loop = true; // unblock clients } 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 ); } thread Server {}; void main( Server & this ) { for( size_t i = 0; !server_done; i++ ) { if ( i % 4 == 0 ) { fulfil(A, i); fulfil(B, i); } else if ( i % 4 == 1 ) { fulfil(A, i); fulfil(C, i); } else if ( i % 4 == 2 ) { fulfil(B, i); fulfil(C, i); } else { fulfil(C, 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: sout | "Usage: " | argv[0] | " [ clients (> 0) | 'd' (default " | Clients | ") ] [ time (>= 0) | 'd' (default " | Time | ") ]" ; exit( EXIT_FAILURE ); } // switch processor p[Clients]; { Client c[Clients]; { Server s; sleep(Time`s); server_done = true; } while( available(A) || available(B) || available(C) ) {} client_done = true; fulfil( C, 0 ); } printf("%zu\n", globalTotal); }