#include #include #include #include #include // getpid monitor Buffer { condition full, empty; int front, back, count; int elements[20]; }; void ?{}( Buffer & buffer ) { buffer.front = buffer.back = buffer.count = 0; } int query( Buffer & buffer ) { return buffer.count; } void insert( Buffer & mutex buffer, int elem ) { if ( buffer.count == 20 ) wait( &buffer.empty ); buffer.elements[buffer.back] = elem; buffer.back = ( buffer.back + 1 ) % 20; buffer.count += 1; signal( &buffer.full ); } int remove( Buffer & mutex buffer ) { if ( buffer.count == 0 ) wait( &buffer.full ); int elem = buffer.elements[buffer.front]; buffer.front = ( buffer.front + 1 ) % 20; buffer.count -= 1; signal( &buffer.empty ); return elem; } thread Producer { Buffer * buffer; unsigned int N; }; void main( Producer & prod ) { for ( int i = 1; i <= prod.N; i += 1 ) { yield( (unsigned int)rand48() % 5 ); insert( *prod.buffer, 1 ); } // for insert( *prod.buffer, -1 ); } void ?{}( Producer & prod, Buffer * buffer, unsigned int N ) { prod.buffer = buffer; prod.N = N; } thread Consumer { Buffer * buffer; int * sum; // summation of producer values }; void main( Consumer & cons ) { *cons.sum = 0; for ( ;; ) { yield( (unsigned int)rand48() % 5 ); int item = remove( *cons.buffer ); if ( item == -1 ) break; // sentinel ? *cons.sum += item; } // for } void ?{}( Consumer & cons, Buffer * buffer, int * sum ) { cons.buffer = buffer; cons.sum = sum; } int main() { Buffer buffer; enum { Prods = 5, Cons = 5 }; Producer * prods[Prods]; Consumer * cons[Cons]; const int Sentinel = -1; int sums[Cons]; int i; processor p; //rand48seed( getpid() ); rand48seed( 1003 ); for ( i = 0; i < Cons; i += 1 ) { // create consumers cons[i] = new( &buffer, &sums[i] ); } // for for ( i = 0; i < Prods; i += 1 ) { // create producers prods[i] = new( &buffer, 100000u ); } // for for ( i = 0; i < Prods; i += 1 ) { // wait for producers to finish delete( prods[i] ); } // for for ( i = 0; i < Cons; i += 1 ) { // generate sentinal values to stop consumers insert( buffer, Sentinel ); } // for int sum = 0; for ( i = 0; i < Cons; i += 1 ) { // wait for consumers to finish delete( cons[i] ); sum += sums[i]; } // for sout | "total:" | sum | endl; }