Title: Monitors
1Monitors
2Semaphores unstructured
- Semaphores are the gotos of concurrent
programming - Why?
- Can we do better?
3Bounded buffer (4.9)
proctype Producer( ) byte I 0 byte
Local_Count 0 loop Produce( I )
if_then( Local_Count N )
WaitSemaphore( Not_Full ) end_if_then
B In_Ptr I WaitSemaphore( S )
Count Local_Count Count
SignalSemaphore( S ) if_then( Local_Count
1 ) SignalSemaphore( Not_Empty )
end_if_then In_Ptr ( In_Ptr 1 ) N
end_loop
- Where do the calls to Signal and Wait go?
- Not_Full Not_Empty are a team, yet they are
used all over the place
4Idea
- An operating system monitors the use of the
resources with HW support - Priorities
- interrupt enable/disable
- Generalise this with SW only
- Provide one monitor for one specific purpose
- Encapsulate the resources and operations
Resources Count, B, In_Ptr, Out_Ptr
5Bounded buffer
proctype Producer( ) byte I loop
Produce( I ) Append( I )
end_loop proctype Consumer( ) byte X
loop Take( X ) end_loop
Take
Append
Consumer process
Producer process
6Mutex and synchronisation
- Semaphore
- Mutex S
- Synchronisation Not_Empty, Not_Full
- Monitor
- Automatic
- Condition variables Not_Empty, Not_Full
7Class for data and operations
DeclareMonitor( Producer_Consumer ) byte
BN 0 byte In_Ptr 0 byte Out_Ptr 0
byte Count 0 DeclareCondition(
Not_Empty ) DeclareCondition( Not_Full )
inline Append ( I ) inline Take( X )
/ End Monitor Producer_Consumer /
Encapsulation
Synchronisation
Interface
8Take Append
Check out the errata
inline Append ( I ) EnterMonitor
if_then( Count N ) WaitCondition(
Not_Full ) end_if_then B In_Ptr
I In_Ptr ( In_Ptr 1 ) N
Count SignalCondition( Not_Empty )
LeaveMonitor
inline Take( I ) EnterMonitor
if_then( Count 0 ) WaitCondition(
Not_Empty ) end_if_then I B
Out_Ptr Out_Ptr ( Out_Ptr 1 ) N
Count-- SignalCondition( Not_Full
) LeaveMonitor
9SPIN demo
- See fig5_1.prom, for.h
- Simulate
- Data vales, Message Sequence Chart
- Check Safety
- Deadlock, assert
- Check Liveness
10Condition variables (1)
- Wait( C )
- Suspend calling process on a FIFO queue
associated with C leave the monitor - Signal( C )
- If the queue for C is non empty, run the process
at the head of the queue - Non_Empty( C)
- Return true if the queue for C is non empty
P1 signals P2 who is in and who is out?
11Immediate Resumption Requirement
Signal and leave, and reschedule the woken
process
Consumer1
Consumer2
inline Append ( I ) EnterMonitor
if_then( Count N ) WaitCondition(
Not_Full ) end_if_then B In_Ptr
I In_Ptr ( In_Ptr 1 ) N
Count SignalCondition( Not_Empty )
LeaveMonitor
inline Take( I ) EnterMonitor
if_then( Count 0 ) WaitCondition(
Not_Empty ) end_if_then I B
Out_Ptr Out_Ptr ( Out_Ptr 1 ) N
Count-- SignalCondition( Not_Full
) LeaveMonitor
Producer
12Condition variables (2)
- A condition variable C is memoryless, there is no
counter associated with C - A signal on an empty queue does nothing
- If you want to know how many processes are in the
queue, maintain a separate counter
13Emulating semaphores
Semaphore_Wait ? WaitSemaphore ? WaitCondition
inline Semaphore_Wait () EnterMonitor
if_then( S 0 ) WaitCondition(
Not_Zero ) end_if_then S--
LeaveMonitor inline Semaphore_Signal ()
EnterMonitor S SignalCondition(
Not_Zero ) LeaveMonitor
What type of semaphore do we have here?
- Monitor variable holds semaphore value S
- Condition variable for synchronisation
- Semaphore invariant
- S 0
- S S0 Signals - Completed Waits
- Proof by induction
Check out the errata
14SPIN demo
- See fig5_3.prom, monitor.h, critical.h
- Simulate
- Data vales, Message Sequence Chart
- Check Safety
- Deadlock, assert
- Check Liveness
15Monitor emulation
- See monitor.h, gensem.h
- Semaphore to guarantee mutex
- One semaphore per condition variable
- Immediate resumption
16Readers Writers
- Readers dont exclude other readers
- Writers exclude everyone else
- Readers gt 0 ? Writing
- Writing ? Readers 0
proctype Writer( ) loop Start_Write( )
... End_Write( ) end_loop
proctype Reader( ) loop Start_Read( )
... End_Read( ) end_loop
17Monitor solution
- Count the number of readers
- Writing flag
- Ok_to_Read to control reading
- Ok_to_Write to control writing
18SPIN demo
- See fig5_5.prom, monitor.h, for.h
- Simulate
- Data vales, Message Sequence Chart
- Check Safety
- Deadlock, assert
- Checking liveness takes long
19Monitors in Java
- A Class with qualified declarations
- private for all variables
- synchronized for all methods
- No conditions but every object has
- public final void notifyAll()
- public final void wait() throws
interruptedException
20Conclusions
- A monitor is
- A synchronisation primitive
- High level, structured
- A decentralised version of the monolithic monitor
- A means to encapsulate data and operations
- Caveats
- Make sure conditions persist when (re)-entering
- Compiler support needed
- Same power as semaphores
- Variations possible