#include #include #include #include #include #include #include size_t total_operations = 0; ssize_t Processors = 1, Tasks = 5, BarrierSize = 2; // must be signed typedef channel( int ) Channel; Channel * barWait; Channel * entryWait; owner_lock o; bool done = false; size_t tasks_done = 0; static inline void initBarrier() { for ( j; BarrierSize ) insert( *entryWait, j ); } static inline void barrier() { int ticket = remove( *entryWait ); if ( ticket == BarrierSize - 1 ) { for ( j; BarrierSize - 1 ) insert( *barWait, j ); return; } ticket = remove( *barWait ); // last one out if ( BarrierSize == 1 || ticket == BarrierSize - 2 ) { for ( j; BarrierSize ) insert( *entryWait, j ); } } thread Task {}; static inline void ?{}( Task & p, cluster & clu ) { ((thread &)p){ clu }; } void main(Task & this) { size_t runs = 0; try { for ( ;; ) { if ( done ) break; barrier(); runs++; } } catch ( channel_closed * e ) {} lock(o); total_operations += runs; // sout | "P: " | runs; unlock(o); } int main( int argc, char * argv[] ) { switch ( argc ) { case 3: if ( strcmp( argv[2], "d" ) != 0 ) { // default ? BarrierSize = ato( argv[2] ); if ( Processors < 1 ) fallthru default; } // if case 2: if ( strcmp( argv[1], "d" ) != 0 ) { // default ? Processors = ato( argv[1] ); if ( Processors < 1 ) fallthru default; } // if case 1: // use defaults break; default: exit | "Usage: " | argv[0] | " [ processors (> 0) | 'd' (default " | Processors | ") ] [ BarrierSize (> 0) | 'd' (default " | BarrierSize | ") ]" ; } // switch if ( Tasks < BarrierSize ) Tasks = BarrierSize; size_t Clusters = 1; // create a cluster cluster clus[Clusters]; processor * proc[Processors]; for ( i; Processors ) { (*(proc[i] = malloc())){clus[i % Clusters]}; } Channel entry{ BarrierSize }; Channel wait{ BarrierSize }; entryWait = &entry; barWait = &wait; initBarrier(); sout | "start"; Task * t[Tasks]; for ( i; Tasks ) { (*(t[i] = malloc())){ clus[i % Clusters] }; } sleep(10`s); done = true; sout | "sleep"; close( entry ); close( wait ); for ( i; Tasks ) { delete(t[i]); } // sout | total_operations; for ( i; Processors ) { delete(proc[i]); } sout | "done"; return 0; }