Reader Writer Problem
Description
The problem consists of readers and writers that share a data resource. The readers only want to read from the resource, the writers want to write to it. Obviously, there is no problem if two or more readers access the resource simultaneously. However, if a writer and a reader or two writers access the resource simultaneously, the result becomes indeterminable. Therefore the writers must have exclusive access to the resource.
Diagram
Basically, reader and writer entrance are synchronization regions. Reader and writer are mutual excluded. And writer region has bound one.
.
Synchronization Specification
Cluster: RW ;
Regions: Reader, Writer;
Invariant: Exclusion(Reader,Writer) + Bound(Writer,1) ;
Patterns Used
Global Invariant
Unbounded Global Invariant
(R_in - R_out == 0 or W_in - W_out == 0) and (W_in - W_out <= 1)
Bounded Global Invariant Counter Version
(E1_0 == 0 or E1_1 == 0) and (B1 <= 1)
Core Functional Code
class RW$fine
{
public static void main ( String argv [ ] )
{
new Reader ( ) . start ( ) ;
new Reader ( ) . start ( ) ;
new Writer ( ) . start ( ) ;
new Writer ( ) . start ( ) ;
}
}
final class Reader extends Thread
{
public void run ( )
{
while ( true )
{
/*** RW Reader enter ***/
System . out . println ( "reader reading:" ) ;
System . out . println ( "done reading" ) ;
/*** RW Reader exit ***/
}
}
}
final class Writer extends Thread
{
public void run ( )
{
while ( true )
{
/*** RW Writer enter ***/
System . out . println ( "writer writing:" ) ;
System . out . println ( "done writing" ) ;
/*** RW Writer exit ***/
}
}
}
Unbounded Coarse-Grain Solution
CLUSTER: RW
STATE SPACE VARIABLES: Reader_in, Reader_out, Writer_in, Writer_out;
REGION: Reader
ENTER: <AWAIT Writer_in == Writer_out --> Reader_in++;>
NOTIFY: ;
NOTIFYALL: ;
EXIT: <Reader_out++;>
NOTIFY: ;
NOTIFYALL: Writer_in;REGION: Writer
ENTER: <AWAIT Reader_in == Reader_out && Writer_in == Writer_out --> Writer_in++;>
NOTIFY: ;
NOTIFYALL: ;
EXIT: <Writer_out++;>
NOTIFY: Writer_in;
NOTIFYALL: Reader_in;
Bounded Counter Coarse-Grain Solution
CLUSTER: RW
STATE SPACE VARIABLES: E1_0, E1_1, B1;
LOCAL VARIABLES: ;
REGION: Reader
ENTER: <AWAIT E1_1 == 0 --> E1_0++;>
NOTIFY: ;
NOTIFYALL: ;
EXIT: <E1_0--;>
NOTIFY: ;
NOTIFYALL: Writer_in;REGION: Writer
ENTER: <AWAIT E1_0 == 0 && B1 == 0 --> E1_1++;B1++;>
NOTIFY: ;
NOTIFYALL: ;
EXIT: <E1_1--;B1--;>
NOTIFY: Writer_in;
NOTIFYALL: Reader_in;
Unbounded Fine-Grain Solution
class SGCluster$RW { // counter for Reader region: private static int Reader_in, Reader_out; // counter for Writer region: private static int Writer_in, Writer_out; private static Object clusterCounterLock = new Object(); /**======================================================** ** ** Generated lock and methods for await: Reader$enter ** **======================================================**/ private static Object condition$Reader$enter = new Object(); public static void Reader$enter(){ synchronized (condition$Reader$enter) { while ( !check$Reader$enter()) try { condition$Reader$enter.wait(); } catch (InterruptedException e){} } } private static boolean check$Reader$enter() { synchronized (clusterCounterLock) { if (Writer_in == Writer_out ) { Reader_in ++ ; return true; } else return false; } } /**======================================================** ** ** Generated lock and methods for atomic: Reader$exit ** **======================================================**/ public static void Reader$exit() { synchronized (clusterCounterLock) { Reader_out ++ ; } synchronized (condition$Writer$enter) { condition$Writer$enter.notify(); } } /**======================================================** ** ** Generated lock and methods for await: Writer$enter ** **======================================================**/ private static Object condition$Writer$enter = new Object(); public static void Writer$enter(){ synchronized (condition$Writer$enter) { while ( !check$Writer$enter()) try { condition$Writer$enter.wait(); } catch (InterruptedException e){} } } private static boolean check$Writer$enter() { synchronized (clusterCounterLock) { if (Reader_in == Reader_out && Writer_in == Writer_out ) { Writer_in ++ ; return true; } else return false; } } /**======================================================** ** ** Generated lock and methods for atomic: Writer$exit ** **======================================================**/ public static void Writer$exit() { synchronized (clusterCounterLock) { Writer_out ++ ; } synchronized (condition$Writer$enter) { condition$Writer$enter.notify(); } synchronized (condition$Reader$enter) { condition$Reader$enter.notifyAll(); } } }
Bounded Fine-Grain Solution
class SGCluster$RW { // STATE SPACE VARIABLES: private static int Reader_in , Reader_out , Writer_in , Writer_out ; // LOCAL VARIABLES: private static Object clusterCounterLock = new Object(); /**======================================================** ** ** Generated lock and methods for await: Reader$enter ** **======================================================**/ private static Object condition$Reader$enter = new Object(); public static void Reader$enter(){ synchronized (condition$Reader$enter) { while ( !check$Reader$enter()) try { condition$Reader$enter.wait(); } catch (InterruptedException e){} } } private static boolean check$Reader$enter() { synchronized (clusterCounterLock) { if (Writer_in == Writer_out ) { Reader_in ++ ; ; return true; } else return false; } } /**======================================================** ** ** Generated lock and methods for atomic: Reader$exit ** **======================================================**/ public static void Reader$exit() { synchronized (clusterCounterLock) { Reader_out ++ ; ; } synchronized (condition$Writer$enter) { condition$Writer$enter.notifyAll(); } } /**======================================================** ** ** Generated lock and methods for await: Writer$enter ** **======================================================**/ private static Object condition$Writer$enter = new Object(); public static void Writer$enter(){ synchronized (condition$Writer$enter) { while ( !check$Writer$enter()) try { condition$Writer$enter.wait(); } catch (InterruptedException e){} } } private static boolean check$Writer$enter() { synchronized (clusterCounterLock) { if (Reader_in == Reader_out && Writer_in == Writer_out ) { Writer_in ++ ; ; return true; } else return false; } } /**======================================================** ** ** Generated lock and methods for atomic: Writer$exit ** **======================================================**/ public static void Writer$exit() { synchronized (clusterCounterLock) { Writer_out ++ ; ; } synchronized (condition$Writer$enter) { condition$Writer$enter.notify(); } synchronized (condition$Reader$enter) { condition$Reader$enter.notifyAll(); } } }


