-
Notifications
You must be signed in to change notification settings - Fork 223
Expand file tree
/
Copy pathGermanControl.tla
More file actions
128 lines (107 loc) · 3.7 KB
/
Copy pathGermanControl.tla
File metadata and controls
128 lines (107 loc) · 3.7 KB
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
----------------------------- MODULE GermanControl -----------------------------
CONSTANTS
NODE,
NoNode
ASSUME NoNodeNotInNODE == NoNode \notin NODE
CacheState == {"I", "S", "E"}
VARIABLES
cache,
chan1,
chan2,
chan3,
invSet,
shrSet,
exGntd,
curCmd,
curPtr
vars == <<cache, chan1, chan2, chan3, invSet, shrSet, exGntd, curCmd, curPtr>>
-------------------------------------------------------------------------------
TypeOK ==
/\ cache \in [NODE -> CacheState]
/\ chan1 \in [NODE -> {"Empty", "ReqS", "ReqE"}]
/\ chan2 \in [NODE -> {"Empty", "Inv", "GntS", "GntE"}]
/\ chan3 \in [NODE -> {"Empty", "InvAck"}]
/\ invSet \subseteq NODE
/\ shrSet \subseteq NODE
/\ exGntd \in BOOLEAN
/\ curCmd \in {"Empty", "ReqS", "ReqE"}
/\ curPtr \in NODE \cup {NoNode}
Init ==
/\ cache = [i \in NODE |-> "I"]
/\ chan1 = [i \in NODE |-> "Empty"]
/\ chan2 = [i \in NODE |-> "Empty"]
/\ chan3 = [i \in NODE |-> "Empty"]
/\ invSet = {}
/\ shrSet = {}
/\ exGntd = FALSE
/\ curCmd = "Empty"
/\ curPtr = NoNode
-------------------------------------------------------------------------------
SendReq(i) ==
/\ chan1[i] = "Empty"
/\ \E c \in {"ReqS", "ReqE"} :
/\ cache[i] \in (IF c = "ReqS" THEN {"I"} ELSE {"I", "S"})
/\ chan1' = [chan1 EXCEPT ![i] = c]
/\ UNCHANGED <<cache, chan2, chan3, invSet, shrSet, exGntd, curCmd, curPtr>>
RecvReq(i) ==
/\ curCmd = "Empty"
/\ chan1[i] \in {"ReqS", "ReqE"}
/\ curCmd' = chan1[i]
/\ curPtr' = i
/\ chan1' = [chan1 EXCEPT ![i] = "Empty"]
/\ invSet' = shrSet
/\ UNCHANGED <<cache, chan2, chan3, shrSet, exGntd>>
SendInv(i) ==
/\ chan2[i] = "Empty"
/\ i \in invSet
/\ (curCmd = "ReqE" \/ (curCmd = "ReqS" /\ exGntd = TRUE))
/\ chan2' = [chan2 EXCEPT ![i] = "Inv"]
/\ invSet' = invSet \ {i}
/\ UNCHANGED <<cache, chan1, chan3, shrSet, exGntd, curCmd, curPtr>>
SendInvAck(i) ==
/\ chan2[i] = "Inv"
/\ chan3[i] = "Empty"
/\ chan2' = [chan2 EXCEPT ![i] = "Empty"]
/\ chan3' = [chan3 EXCEPT ![i] = "InvAck"]
/\ cache' = [cache EXCEPT ![i] = "I"]
/\ UNCHANGED <<chan1, invSet, shrSet, exGntd, curCmd, curPtr>>
RecvInvAck(i) ==
/\ chan3[i] = "InvAck"
/\ curCmd # "Empty"
/\ chan3' = [chan3 EXCEPT ![i] = "Empty"]
/\ shrSet' = shrSet \ {i}
/\ exGntd' = IF exGntd = TRUE THEN FALSE ELSE exGntd
/\ UNCHANGED <<cache, chan1, chan2, invSet, curCmd, curPtr>>
SendGnt(i) ==
/\ curCmd \in {"ReqS", "ReqE"}
/\ curPtr = i
/\ chan2[i] = "Empty"
/\ exGntd = FALSE
/\ curCmd = "ReqE" => shrSet = {}
/\ chan2' = [chan2 EXCEPT ![i] = IF curCmd = "ReqS" THEN "GntS" ELSE "GntE"]
/\ shrSet' = shrSet \cup {i}
/\ exGntd' = (curCmd = "ReqE")
/\ curCmd' = "Empty"
/\ curPtr' = NoNode
/\ UNCHANGED <<cache, chan1, chan3, invSet>>
RecvGnt(i) ==
/\ chan2[i] \in {"GntS", "GntE"}
/\ cache' = [cache EXCEPT ![i] = IF chan2[i] = "GntS" THEN "S" ELSE "E"]
/\ chan2' = [chan2 EXCEPT ![i] = "Empty"]
/\ UNCHANGED <<chan1, chan3, invSet, shrSet, exGntd, curCmd, curPtr>>
-------------------------------------------------------------------------------
Next ==
\E i \in NODE :
\/ SendReq(i)
\/ RecvReq(i)
\/ SendInv(i) \/ SendInvAck(i) \/ RecvInvAck(i)
\/ SendGnt(i)
\/ RecvGnt(i)
Spec == Init /\ [][Next]_vars
-------------------------------------------------------------------------------
Coherence ==
\A i, j \in NODE :
i # j =>
/\ (cache[i] = "E" => cache[j] = "I")
/\ (cache[i] = "S" => cache[j] \in {"I", "S"})
=============================================================================