-
Notifications
You must be signed in to change notification settings - Fork 5
/
Peterson.hs
63 lines (54 loc) · 1.82 KB
/
Peterson.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
{-# LANGUAGE DataKinds, ScopedTypeVariables #-}
module Peterson where
import qualified Data.Map as M
import CTL
import ProgramPred
import Types
import ToDot
import StateGraph
nop = Arith $ \s -> [s]
pushI i = Arith $ \s -> [IntValue i:s]
pushB b = Arith $ \s -> [BoolValue b:s]
unopI op = Arith $ \(IntValue a:s) -> [IntValue (op a):s]
unopB op = Arith $ \(BoolValue a:s) -> [BoolValue (op a):s]
cmp op = Arith $ \(IntValue b:IntValue a:s) -> [BoolValue (op a b):s]
-- spin in lock/unlock
petersonThread id myFlag otherFlag victim claim = compile [ Label "loop", Block lock, Block unlock, Jmp "loop" ]
where
lock = [
pushB True,
Set myFlag, -- I'm interested
pushI id,
Set victim, -- You go first
Label "wait",
Get otherFlag, -- if(!otherFlag) break;
unopB not,
JmpCond "leaveLock",
Get victim, -- if(victim != i) break;
pushI id,
cmp (/=),
JmpCond "leaveLock",
Jmp "wait",
Label "leaveLock",
pushB True,
Set claim
]
unlock = [
pushB False,
Set claim,
pushB False,
Set myFlag
]
petersonDriver = initState [("flagA",BoolValue False),
("flagB", BoolValue False),
("victim", IntValue 0),
("claimA", BoolValue False),
("claimB", BoolValue False)] [] $ compile [
Spawn "ta" (petersonThread 1 "flagA" "flagB" "victim" "claimA"),
Spawn "tb" (petersonThread 2 "flagB" "flagA" "victim" "claimB")
]
g = stateGraph petersonDriver 60
formula = CTLPred (\(ma :: BoolVar "claimA") (mb :: BoolVar "claimB") -> value ma && value mb)
badStateIndices = verifySG formula g
badStates = [sg_index2node g M.! i | i <- badStateIndices]
main = putStrLn $ toDot g