#include #include #include #include #include #include #include #include // #define NUM_CHANS 1 #define GLUE_HELPER(x, y) x##y #define FN_GLUE(x, y) GLUE_HELPER(x, y) size_t Processors = 2, Producers = 1, Consumers = 1, ChannelSize = 10; channel(size_t) * chans; static inline void cons_wait_1( size_t & val, size_t & i ) { waituntil( val << chans[0] ) {} or else { i--; } } static inline void cons_wait_2( size_t & val, size_t & i ) { waituntil( val << chans[0] ) {} or waituntil( val << chans[1] ) {} or else { i--; } } static inline void cons_wait_3( size_t & val, size_t & i ) { waituntil( val << chans[0] ) {} or waituntil( val << chans[1] ) {} or waituntil( val << chans[2] ) {} or else { i--; } } static inline void cons_wait_4( size_t & val, size_t & i ) { waituntil( val << chans[0] ) {} or waituntil( val << chans[1] ) {} or waituntil( val << chans[2] ) {} or waituntil( val << chans[3] ) {} or else { i--; } } static inline void cons_wait_5( size_t & val, size_t & i ) { waituntil( val << chans[0] ) {} or waituntil( val << chans[1] ) {} or waituntil( val << chans[2] ) {} or waituntil( val << chans[3] ) {} or waituntil( val << chans[4] ) {} or else { i--; } } static inline void cons_wait_6( size_t & val, size_t & i ) { waituntil( val << chans[0] ) {} or waituntil( val << chans[1] ) {} or waituntil( val << chans[2] ) {} or waituntil( val << chans[3] ) {} or waituntil( val << chans[4] ) {} or waituntil( val << chans[5] ) {} or else { i--; } } static inline void cons_wait_7( size_t & val, size_t & i ) { waituntil( val << chans[0] ) {} or waituntil( val << chans[1] ) {} or waituntil( val << chans[2] ) {} or waituntil( val << chans[3] ) {} or waituntil( val << chans[4] ) {} or waituntil( val << chans[5] ) {} or waituntil( val << chans[6] ) {} or else { i--; } } static inline void cons_wait_8( size_t & val, size_t & i ) { waituntil( val << chans[0] ) {} or waituntil( val << chans[1] ) {} or waituntil( val << chans[2] ) {} or waituntil( val << chans[3] ) {} or waituntil( val << chans[4] ) {} or waituntil( val << chans[5] ) {} or waituntil( val << chans[6] ) {} or waituntil( val << chans[7] ) {} or else { i--; } } static inline void prods_wait_1( size_t val ) { waituntil( val >> chans[0] ) {} or else {} } static inline void prods_wait_2( size_t val ) { waituntil( val >> chans[0] ) {} or waituntil( val >> chans[1] ) {} or else {} } static inline void prods_wait_3( size_t val ) { waituntil( val >> chans[0] ) {} or waituntil( val >> chans[1] ) {} or waituntil( val >> chans[2] ) {} or else {} } static inline void prods_wait_4( size_t val ) { waituntil( val >> chans[0] ) {} or waituntil( val >> chans[1] ) {} or waituntil( val >> chans[2] ) {} or waituntil( val >> chans[3] ) {} or else {} } static inline void prods_wait_5( size_t val ) { waituntil( val >> chans[0] ) {} or waituntil( val >> chans[1] ) {} or waituntil( val >> chans[2] ) {} or waituntil( val >> chans[3] ) {} or waituntil( val >> chans[4] ) {} or else {} } static inline void prods_wait_6( size_t val ) { waituntil( val >> chans[0] ) {} or waituntil( val >> chans[1] ) {} or waituntil( val >> chans[2] ) {} or waituntil( val >> chans[3] ) {} or waituntil( val >> chans[4] ) {} or waituntil( val >> chans[5] ) {} or else {} } static inline void prods_wait_7( size_t val ) { waituntil( val >> chans[0] ) {} or waituntil( val >> chans[1] ) {} or waituntil( val >> chans[2] ) {} or waituntil( val >> chans[3] ) {} or waituntil( val >> chans[4] ) {} or waituntil( val >> chans[5] ) {} or waituntil( val >> chans[6] ) {} or else {} } static inline void prods_wait_8( size_t val ) { waituntil( val >> chans[0] ) {} or waituntil( val >> chans[1] ) {} or waituntil( val >> chans[2] ) {} or waituntil( val >> chans[3] ) {} or waituntil( val >> chans[4] ) {} or waituntil( val >> chans[5] ) {} or waituntil( val >> chans[6] ) {} or waituntil( val >> chans[7] ) {} or else {} } size_t globalTotal = 0; thread Consumer {}; void main( Consumer & this ) { size_t val, i = 0; try { for(;; i++ ) { FN_GLUE(cons_wait_, NUM_CHANS)(val, i); } } catch( channel_closed * e ) {} __atomic_fetch_add( &globalTotal, i, __ATOMIC_SEQ_CST ); } thread Producer {}; void main( Producer & this ) { try { for( size_t i = 0;; i++ ) { FN_GLUE(prods_wait_, NUM_CHANS)(i); } } catch( channel_closed * e ) {} } int main( int argc, char * argv[] ) { switch ( argc ) { case 3: if ( strcmp( argv[2], "d" ) != 0 ) { // default ? ChannelSize = atoi( argv[2] ); } // if case 2: if ( strcmp( argv[1], "d" ) != 0 ) { // default ? Processors = atoi( argv[1] ); if ( Processors < 1 ) goto Usage; } // if case 1: // use defaults break; default: Usage: sout | "Usage: " | argv[0] | " [ processors (> 0) | 'd' (default " | Processors | ") ] [ channel size (>= 0) | 'd' (default " | ChannelSize | ") ]" ; exit( EXIT_FAILURE ); } // switch Producers = Processors / 2; Consumers = Processors / 2; processor p[Processors - 1]; chans = aalloc( NUM_CHANS ); for ( i; NUM_CHANS ) chans[i]{ ChannelSize }; { Producer p[Producers]; Consumer c[Consumers]; sleep(10`s); for ( i; NUM_CHANS ) close( chans[i] ); } adelete( chans ); printf("%zu\n", globalTotal); }