| 1 | #include <select.hfa>
 | 
|---|
| 2 | #include <thread.hfa>
 | 
|---|
| 3 | #include <channel.hfa>
 | 
|---|
| 4 | #include <time.hfa>
 | 
|---|
| 5 | 
 | 
|---|
| 6 | channel(long long int) A, B, C, D, E, F;
 | 
|---|
| 7 | 
 | 
|---|
| 8 | volatile long long int inserts = 0;
 | 
|---|
| 9 | volatile long long int removes = 0;
 | 
|---|
| 10 | 
 | 
|---|
| 11 | thread Producer {};
 | 
|---|
| 12 | void main( Producer & this ) {
 | 
|---|
| 13 |     long long int my_inserts = 0;
 | 
|---|
| 14 |     long long int A_i = 0, B_i = 0, C_i = 0, D_i = 0, E_i = 0, F_i = 0;
 | 
|---|
| 15 |     try {
 | 
|---|
| 16 |         for( long long int i = 0;;i++ ) {
 | 
|---|
| 17 |             waituntil( A << i ) { A_i++; }
 | 
|---|
| 18 |             and waituntil( B << i ) { B_i++; }
 | 
|---|
| 19 |             and waituntil( C << i ) { C_i++; }
 | 
|---|
| 20 |             and waituntil( D << i ) { D_i++; }
 | 
|---|
| 21 |             and waituntil( E << i ) { E_i++; }
 | 
|---|
| 22 |             and waituntil( F << i ) { F_i++; }
 | 
|---|
| 23 |         }
 | 
|---|
| 24 |     } catch ( channel_closed * e ) {} 
 | 
|---|
| 25 |     __atomic_fetch_add( &inserts, A_i + B_i + C_i + D_i + E_i + F_i, __ATOMIC_SEQ_CST );
 | 
|---|
| 26 | }
 | 
|---|
| 27 | 
 | 
|---|
| 28 | thread Consumer {};
 | 
|---|
| 29 | void main( Consumer & this ) {
 | 
|---|
| 30 |     long long int in, A_removes = 0, B_removes = 0, C_removes = 0, D_removes = 0, E_removes = 0, F_removes = 0;
 | 
|---|
| 31 |     try {
 | 
|---|
| 32 |         for( ;; ) {
 | 
|---|
| 33 |             waituntil( remove(F) ) { F_removes++; }
 | 
|---|
| 34 |             or waituntil( remove(E) ) { E_removes++; }
 | 
|---|
| 35 |             or waituntil( remove(D) ) { D_removes++; }
 | 
|---|
| 36 |             or waituntil( remove(C) ) { C_removes++; }
 | 
|---|
| 37 |             or waituntil( remove(B) ) { B_removes++; }
 | 
|---|
| 38 |             or waituntil( remove(A) ) { A_removes++; }
 | 
|---|
| 39 |         }
 | 
|---|
| 40 |     } catchResume ( channel_closed * e ) { } // continue to remove until would block
 | 
|---|
| 41 |     catch ( channel_closed * e ) {}
 | 
|---|
| 42 |     try {
 | 
|---|
| 43 |         for( ;; )
 | 
|---|
| 44 |             waituntil( (in << A) ) { A_removes++; }
 | 
|---|
| 45 |     } catchResume ( channel_closed * e ) {} // continue to remove until would block
 | 
|---|
| 46 |     catch ( channel_closed * e ) {}
 | 
|---|
| 47 |     try {
 | 
|---|
| 48 |         for( ;; )
 | 
|---|
| 49 |             waituntil( (in << B) ) { B_removes++; }
 | 
|---|
| 50 |     } catchResume ( channel_closed * e ) {} // continue to remove until would block
 | 
|---|
| 51 |     catch ( channel_closed * e ) {}
 | 
|---|
| 52 |     try {
 | 
|---|
| 53 |         for( ;; )
 | 
|---|
| 54 |             waituntil( (in << C) ) { C_removes++; }
 | 
|---|
| 55 |     } catchResume ( channel_closed * e ) {} // continue to remove until would block
 | 
|---|
| 56 |     catch ( channel_closed * e ) {}
 | 
|---|
| 57 |     try {
 | 
|---|
| 58 |         for( ;; )
 | 
|---|
| 59 |             waituntil( (in << D) ) { D_removes++; }
 | 
|---|
| 60 |     } catchResume ( channel_closed * e ) {} // continue to remove until would block
 | 
|---|
| 61 |     catch ( channel_closed * e ) {}
 | 
|---|
| 62 |     try {
 | 
|---|
| 63 |         for( ;; )
 | 
|---|
| 64 |             waituntil( (in << E) ) { E_removes++; }
 | 
|---|
| 65 |     } catchResume ( channel_closed * e ) {} // continue to remove until would block
 | 
|---|
| 66 |     catch ( channel_closed * e ) {}
 | 
|---|
| 67 |     try {
 | 
|---|
| 68 |         for( ;; )
 | 
|---|
| 69 |             waituntil( (in << F) ) { F_removes++; }
 | 
|---|
| 70 |     } catchResume ( channel_closed * e ) {} // continue to remove until would block
 | 
|---|
| 71 |     catch ( channel_closed * e ) {}
 | 
|---|
| 72 |     __atomic_fetch_add( &removes, A_removes + B_removes + C_removes + D_removes + E_removes + F_removes, __ATOMIC_SEQ_CST );
 | 
|---|
| 73 | }
 | 
|---|
| 74 | 
 | 
|---|
| 75 | 
 | 
|---|
| 76 | size_t time = 3, num_times = 10, chan_size = 0, num_thds = 2;
 | 
|---|
| 77 | int main( int argc, char * argv[] ) {
 | 
|---|
| 78 |     if ( argc == 2 )
 | 
|---|
| 79 |         time = atoi( argv[1] );
 | 
|---|
| 80 | 
 | 
|---|
| 81 |     processor p[ num_thds - 1 ];
 | 
|---|
| 82 | 
 | 
|---|
| 83 |     printf("Start\n");
 | 
|---|
| 84 |     for ( i; num_times ) {
 | 
|---|
| 85 |         printf("%lu\n", i);
 | 
|---|
| 86 |         A{chan_size};
 | 
|---|
| 87 |         B{chan_size};
 | 
|---|
| 88 |         C{chan_size};
 | 
|---|
| 89 |         D{chan_size};
 | 
|---|
| 90 |         E{chan_size};
 | 
|---|
| 91 |         F{chan_size};
 | 
|---|
| 92 |         {
 | 
|---|
| 93 |             Producer p[ num_thds / 2 ];
 | 
|---|
| 94 |             Consumer c[ num_thds / 2 ];
 | 
|---|
| 95 |             sleep(time`s);
 | 
|---|
| 96 |             close(A);
 | 
|---|
| 97 |             close(B);
 | 
|---|
| 98 |             close(C);
 | 
|---|
| 99 |             close(D);
 | 
|---|
| 100 |             close(E);
 | 
|---|
| 101 |             close(F);
 | 
|---|
| 102 |         }
 | 
|---|
| 103 |         if ( inserts != removes ) {
 | 
|---|
| 104 |             printf("\n");
 | 
|---|
| 105 |             printf("CHECKSUM MISMATCH!! Producer got: %lld, Consumer got: %lld\n", inserts, removes);
 | 
|---|
| 106 |             assert(false);
 | 
|---|
| 107 |         }
 | 
|---|
| 108 |         ^A{};
 | 
|---|
| 109 |         ^B{};
 | 
|---|
| 110 |         ^C{};
 | 
|---|
| 111 |         ^D{};
 | 
|---|
| 112 |         ^E{};
 | 
|---|
| 113 |         ^F{};
 | 
|---|
| 114 | 
 | 
|---|
| 115 |         inserts = 0;
 | 
|---|
| 116 |         removes = 0;
 | 
|---|
| 117 |     }
 | 
|---|
| 118 | 
 | 
|---|
| 119 |     A{5};
 | 
|---|
| 120 |     B{5};
 | 
|---|
| 121 |     C{5};
 | 
|---|
| 122 |     D{5};
 | 
|---|
| 123 |     E{5};
 | 
|---|
| 124 |     F{5};
 | 
|---|
| 125 |     printf("Done\n");
 | 
|---|
| 126 | }
 | 
|---|