| [7bef8cf] | 1 | #include <fstream.hfa>
 | 
|---|
 | 2 | #include <thread.hfa>
 | 
|---|
 | 3 | 
 | 
|---|
 | 4 | volatile int SharedRW = 0;                                                              // shared variable to test readers and writers
 | 
|---|
 | 5 | 
 | 
|---|
 | 6 | monitor ReadersWriter {
 | 
|---|
 | 7 |         int rcnt, wcnt;                                                                         // number of readers/writer using resource
 | 
|---|
 | 8 | };
 | 
|---|
 | 9 | 
 | 
|---|
 | 10 | void ?{}( ReadersWriter & rw ) with(rw) { rcnt = wcnt = 0; }
 | 
|---|
 | 11 | void EndRead( ReadersWriter & mutex rw ) with(rw) { rcnt -= 1; }
 | 
|---|
 | 12 | void EndWrite( ReadersWriter & mutex rw ) with(rw) { wcnt = 0; }
 | 
|---|
 | 13 | void StartRead( ReadersWriter & mutex rw ) with(rw) {
 | 
|---|
 | 14 |         if ( wcnt > 0 ) waitfor( EndWrite : rw );
 | 
|---|
 | 15 |         rcnt += 1;
 | 
|---|
 | 16 | }
 | 
|---|
 | 17 | void StartWrite( ReadersWriter & mutex rw ) with(rw) {
 | 
|---|
 | 18 |         if ( wcnt > 0 ) waitfor( EndWrite : rw );
 | 
|---|
 | 19 |         else while ( rcnt > 0 ) waitfor( EndRead : rw );
 | 
|---|
 | 20 |         wcnt = 1;
 | 
|---|
 | 21 | }
 | 
|---|
 | 22 | int readers( ReadersWriter & rw ) { return rw.rcnt; }
 | 
|---|
 | 23 | 
 | 
|---|
 | 24 | void Read( ReadersWriter & rw ) {
 | 
|---|
 | 25 |         StartRead( rw );
 | 
|---|
 | 26 |         sout | "Reader:" | active_thread() | ", shared:" | SharedRW | " with:" | readers( rw ) | " readers";
 | 
|---|
 | 27 |         yield( 3 );
 | 
|---|
 | 28 |         EndRead( rw );
 | 
|---|
 | 29 | }
 | 
|---|
 | 30 | void Write( ReadersWriter & rw ) {
 | 
|---|
 | 31 |         StartWrite( rw );
 | 
|---|
 | 32 | 
 | 
|---|
 | 33 |         SharedRW += 1;
 | 
|---|
 | 34 |         sout | "Writer:" | active_thread() | ",  wrote:" | SharedRW;
 | 
|---|
 | 35 |         yield( 1 );
 | 
|---|
 | 36 |         EndWrite( rw );
 | 
|---|
 | 37 | }
 | 
|---|
 | 38 | 
 | 
|---|
 | 39 | thread Worker {
 | 
|---|
 | 40 |         ReadersWriter &rw;
 | 
|---|
 | 41 | };
 | 
|---|
 | 42 | void ?{}( Worker & w, ReadersWriter * rw ) { &w.rw = rw; }
 | 
|---|
 | 43 | void main( Worker & w ) with(w) {
 | 
|---|
 | 44 |         for ( 10 ) {
 | 
|---|
 | 45 |                 if ( rand() % 100 < 70 ) {                                      // decide to be a reader or writer
 | 
|---|
 | 46 |                         Read( rw );
 | 
|---|
 | 47 |                 } else {
 | 
|---|
 | 48 |                         Write( rw );
 | 
|---|
 | 49 |                 } // if
 | 
|---|
 | 50 |         } // for
 | 
|---|
 | 51 | }
 | 
|---|
 | 52 | 
 | 
|---|
 | 53 | int main() {
 | 
|---|
 | 54 |         enum { MaxTask = 5 };
 | 
|---|
 | 55 |         ReadersWriter rw;
 | 
|---|
 | 56 |         Worker *workers[MaxTask];
 | 
|---|
 | 57 | 
 | 
|---|
 | 58 |         for ( i; MaxTask ) workers[i] = new( &rw );
 | 
|---|
 | 59 |         for ( i; MaxTask ) delete( workers[i] );
 | 
|---|
 | 60 |         sout | "successful completion";
 | 
|---|
 | 61 | } // main
 | 
|---|
 | 62 | 
 | 
|---|
 | 63 | // Local Variables: //
 | 
|---|
 | 64 | // tab-width: 4 //
 | 
|---|
 | 65 | // compile-command: "cfa -O2 RWMonitorEXT.cfa" //
 | 
|---|
 | 66 | // End: //
 | 
|---|