CONCURRENCY, INTUITION AND FORMAL VERIFICATION: YES, WE CAN! BEN-ARI’S TWIN-PROCESS CONUNDRUM MATT PEDERSEN & PETER WELCH Communicating Process Architectures 2017 Fringe
The Problem ¨ Professor Ben-Ari used the problem for a decade (described in “A model checking primer”)
The Problem ¨ 2 Processes P and Q run concurrently ¨ Both update a shared variable n (initially 0) ten times. Each update is as follows: ¤ Read n ¤ Increment it locally ¤ Write n back
Pseudo Code integer n = 0; process Q process P integer regQ = 0; integer regP = 0; do 10 times do 10 times load n into regQ load n into regP increment regQ increment regP store regQ into n store regP into n end end
Possible values for n?
The Problem ¨ Professor Ben-Ari used the problem for a decade ¨ Told his students the value would be between 10 and 20
The Problem ¨ Professor Ben-Ari used the problem for a decade. ¨ Told his students the value would be between 10 and 20. ¨ One day a student of his got the value 9 ! ¨ Actually any number between 2 and 20 is possible.
What do we do now? ¨ Start by proving that we can get 2, and how. Problem Assertion CSP FDR Trace
A CSP Model ¨ Channels: channel load, store : {0..20} channel kill ¨ Increment function: inc (x) = if x >= 20 then 20 else x + 1
A CSP Model ¨ The process itself (P and Q): P = ; x:<0..9> @ load ? n à store ! inc (n) à SKIP
A CSP Model ¨ A process representing n: Var (n) = store ? x à Var (x) [] load ! n à Var (n) [] kill à SKIP -- terminate
A CSP Model ¨ A checking process PP_check = (P ||| P); load ? n à if n == 2 then STOP else kill -> SKIP
A CSP Model ¨ The entire system: System = PP_check [| {| load, store, kill |} |] Var (0)
Analysis of the Model PP_check = (P ||| P); load ? n à if n == 2 then STOP else kill -> SKIP ¨ If this process always terminates the value of n cannot be 2. ¨ assert SKIP [FD= System \ Events checks if System always terminates.
Analysis of the Model
Trace leading to n=2
Time P Q n 0 Load 0 0 1 Load 0 0 2 Store 1 1 3 Load 1 1 4 Store 2 2 … 5-16 2-8 17 Load 8 8 18 Store 9 9 19 Store 1 1 20 Load 1 1 21 Load 1 1 22 Store 2 2 … 23-36 2-9 37 Load 9 9 38 Store 10 10 39 Store 2 2
Aside ¨ Did the STOP cause lack of termination? PP_check = (P ||| P); load ? n à if n == 2 then STOP else kill -> SKIP
Aside ¨ Did the STOP cause lack of termination? ¨ Consider this: PP_no_check = (P ||| P); kill à SKIP ¨ Terminates just fine
Correct Behaviour ¨ Introduce a mutex: channel wait, signal Mutex = wait à signal à Mutex [] kill à SKIP
Add use of mutex to P process ¨ Introduce the mutex into the P process (now called P’): P’ = ; x:<0..9> @ wait à load ? N à store ! inc (n) à signal à SKIP
Wire up the system ¨ Lets wire it all up (2 processes and a check): PP_check’ = (P’ ||| P’); load ? n à if n != 20 then STOP else kill à SKIP
Wire up the system ¨ Wire up the entire system and add the mutex: SYSTEM’ = PP_check’ [| {| load, store, kill |} |] Var (0) SAFE_SYSTEM = SYSTEM’ [| {| wait, signal, kill |} |] Mutex
FDR check the SAFE_SYSTEM ¨ Check if the SAFE_SYSTEM terminates: assert SKIP [FD= SAFE_SYSTEM \ Events ¨ It does! ¤ 20 is the only value the variable can have upon termination.
occam-pi demo
Recommend
More recommend