| [a33a5e2] | 1 | #include <select.hfa> | 
|---|
|  | 2 | #include <thread.hfa> | 
|---|
|  | 3 | #include <channel.hfa> | 
|---|
|  | 4 |  | 
|---|
|  | 5 | channel(long long int) A, B, C; | 
|---|
|  | 6 |  | 
|---|
|  | 7 | volatile bool done = false; | 
|---|
|  | 8 | long long int globalTotal = 0; | 
|---|
|  | 9 |  | 
|---|
|  | 10 | thread Server1 {}; | 
|---|
|  | 11 | void main( Server1 & this ) { | 
|---|
|  | 12 | long long int a, b, c, i = 0, myTotal = 0; | 
|---|
|  | 13 | for( ;;i++ ) { | 
|---|
| [a882b68] | 14 | when( i % 2 == 0 ) waituntil( a << A ) { myTotal += a; } | 
|---|
|  | 15 | or when( i % 4 < 2 ) waituntil( b << B ) { myTotal += b; } | 
|---|
|  | 16 | or waituntil( c << C ) { if ( c == -1 ) break; myTotal += c; } | 
|---|
| [a33a5e2] | 17 | or when( i % 8 < 4 ) else {} | 
|---|
|  | 18 | } | 
|---|
|  | 19 | __atomic_fetch_add( &globalTotal, myTotal, __ATOMIC_SEQ_CST ); | 
|---|
|  | 20 | } | 
|---|
|  | 21 |  | 
|---|
|  | 22 | thread Drainer {}; // ensures that the changing when states of Server1 don't result in a deadlock | 
|---|
|  | 23 | void main( Drainer & this ) { | 
|---|
| [a882b68] | 24 | long long int a, b, c, myTotal = 0; | 
|---|
|  | 25 | for( ;; ) { | 
|---|
|  | 26 | waituntil( a << A ) { myTotal += a; } | 
|---|
|  | 27 | or waituntil( b << B ) { myTotal += b; } | 
|---|
|  | 28 | or waituntil( c << C ) { if ( c == -1 ) break; myTotal += c; } | 
|---|
|  | 29 | or else {} | 
|---|
| [a33a5e2] | 30 | } | 
|---|
|  | 31 | __atomic_fetch_add( &globalTotal, myTotal, __ATOMIC_SEQ_CST ); | 
|---|
|  | 32 | } | 
|---|
|  | 33 |  | 
|---|
|  | 34 | thread Churner {}; // performs non-waituntil try insert/remove operations to add churn/interference | 
|---|
|  | 35 | void main( Churner & this ) { | 
|---|
|  | 36 | long long int out, myTotal = 0; | 
|---|
|  | 37 | bool success; | 
|---|
|  | 38 | while( !done ) { | 
|---|
|  | 39 | try_insert( A, 0 ); | 
|---|
|  | 40 | try_insert( B, 0 ); | 
|---|
|  | 41 | try_insert( C, 0 ); | 
|---|
| [a882b68] | 42 | [out, success] = try_remove( A ); | 
|---|
| [a33a5e2] | 43 | if ( success ) myTotal += out; | 
|---|
| [a882b68] | 44 | [out, success] = try_remove( B ); | 
|---|
| [a33a5e2] | 45 | if ( success ) myTotal += out; | 
|---|
| [a882b68] | 46 | [out, success] = try_remove( C ); | 
|---|
| [a33a5e2] | 47 | if ( success ) myTotal += out; | 
|---|
|  | 48 | } | 
|---|
|  | 49 | __atomic_fetch_add( &globalTotal, myTotal, __ATOMIC_SEQ_CST ); | 
|---|
|  | 50 | } | 
|---|
|  | 51 |  | 
|---|
|  | 52 | size_t numtimes = 100000; | 
|---|
|  | 53 | size_t numServers = 3; | 
|---|
|  | 54 | int main( int argc, char * argv[] ) { | 
|---|
|  | 55 | if ( argc == 2 ) | 
|---|
|  | 56 | numtimes = atoi( argv[1] ); | 
|---|
|  | 57 |  | 
|---|
|  | 58 | processor p[numServers + 2]; | 
|---|
|  | 59 | A{5}; | 
|---|
|  | 60 | B{5}; | 
|---|
|  | 61 | C{5}; | 
|---|
|  | 62 |  | 
|---|
|  | 63 | long long int total = 0; | 
|---|
|  | 64 | printf("start\n"); | 
|---|
|  | 65 | { | 
|---|
|  | 66 | Server1 s[numServers]; | 
|---|
|  | 67 | Drainer d; | 
|---|
|  | 68 | { | 
|---|
|  | 69 | Churner c; | 
|---|
|  | 70 | for( long long int j = 0; j < numtimes; j++ ) { | 
|---|
| [a882b68] | 71 | when( j % 2 == 0 ) waituntil( j >> A ) { total += j; } | 
|---|
|  | 72 | or when( j % 4 < 2 ) waituntil( j >> B ) { total += j; } | 
|---|
|  | 73 | and when( j % 8 < 4 ) waituntil( j >> C ) { total += j; } | 
|---|
| [a33a5e2] | 74 | } | 
|---|
|  | 75 | done = true; | 
|---|
|  | 76 | printf("terminating churner\n"); | 
|---|
|  | 77 | } | 
|---|
|  | 78 | printf("waiting for empty channels\n"); | 
|---|
| [a882b68] | 79 | while( get_count( A ) > 0 || get_count( B ) > 0 || get_count( C ) > 0 ) { } | 
|---|
| [a33a5e2] | 80 | printf("sending sentinels\n"); | 
|---|
|  | 81 | for ( i; numServers + 1 ) insert( C, -1 ); | 
|---|
|  | 82 | printf("joining servers\n"); | 
|---|
|  | 83 | } | 
|---|
|  | 84 | if ( total != globalTotal ) | 
|---|
|  | 85 | printf("CHECKSUM MISMATCH!! Main thread got %lld, server sum is %lld\n", total, globalTotal); | 
|---|
|  | 86 | printf("done\n"); | 
|---|
|  | 87 | } | 
|---|