lectureNote8
lectureNote8
lectureNote8
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
I636: Specification and Verification of<br />
Distributed Systems<br />
8. Suzuki‐Kasami Distributed<br />
Mutual Exclusion Protocol (2)<br />
Kazuhiro Ogata & Kokichi Futatsugi<br />
Outline<br />
• The OTS S SK modeling the Suzuki‐Kasami<br />
protocol is specified in Maude.<br />
• We model check that S SK (the Suzuki‐Kasami<br />
protocol) satisfies (or does not satisfy) the<br />
mutual exclusion property and the lockout<br />
freedom property based on the specification.<br />
• This lecture describes how to specify S SK in<br />
Maude and how to model check the two<br />
properties for S SK with Maude.<br />
2
Quick Reminder (1)<br />
• Consists of two procedures P1 and P2 for each node i.<br />
When node i wants to enter the critical section, it calls P1.<br />
procedure P1;<br />
begin<br />
requesting := true;<br />
if not have_privilege then<br />
begin<br />
rn[i] := rn[i] + 1;<br />
for all j in {1,…,N} – {i} do<br />
send request(i,rn[i]) rn[i]) to node j;<br />
wait until privilege(queue,ln)<br />
is received.<br />
have_privilege := true;<br />
end;<br />
Critical Section;<br />
ln[i] := rn[i];<br />
for all j in {1,…,N} – {i} do<br />
if not in(queue,j) and (rn[j] = ln[j] + 1)<br />
then queue := put(queue,j);<br />
if queue ≠ empty then<br />
begin<br />
have_privilege := false;<br />
send privilege(get(queue),ln)<br />
to node top(queue)<br />
end;<br />
requesting := false<br />
end;<br />
3<br />
Quick Reminder (2)<br />
• When node i receives request(j,n), it calls P2, executing<br />
it atomically.<br />
procedure P2;<br />
begin<br />
rn[j] := max(rn[j],n);<br />
if have_privilege and not requesting and (rn[j] = ln[j] + 1) then<br />
begin<br />
have_privilege := false;<br />
variables Initial values<br />
send privilege(queue,ln) iil ( l ) to node j<br />
end<br />
end;<br />
Initially each process is in the section<br />
(called the remainder section) that is<br />
different from the protocol .<br />
requesting<br />
false<br />
have_privilege true if i = 1, and false o/w<br />
rn each element is 0<br />
ln each element is 0<br />
queue<br />
empty<br />
4
Quick Reminder (3)<br />
• The observers used:<br />
– pc : U NodeID → Label<br />
– requesting : U NodeID → Bool<br />
– havePriv : U NodeID → Bool<br />
– rn : U NodeID → Array<br />
– ln : U NodeID → Array<br />
– queue : U NodeID → Queue<br />
– idx : U NodeID → Nat<br />
– nw : U → Network<br />
where NodeID is the type of natural numbers i such that 1 i N,<br />
Label is the type of the locations in the protocol at which nodes<br />
are, Array is the type of natural number arrays of size N, Queue is<br />
the type of queues of NodeID’s, and Network is the type of<br />
multisets of messages.<br />
5<br />
Quick Reminder (4)<br />
• A state u is a initial state if for all NodeID’s i,<br />
– pc(u,i) is rem,<br />
– requesting(u,i) is false,<br />
– havePriv(u,i) is true if i is 1 and false otherwise,<br />
– rn(u,i) is an array such that each element is 0,<br />
– ln(u,i) is an array such that each element is 0,<br />
– queue(u,i) is empty,<br />
– idx(u,i) is an arbitrary natural number, and<br />
– nw(u) is empty.<br />
6
Quick Reminder (5)<br />
• The transitions used:<br />
– try : U NodeID → U<br />
– setReq : U NodeID → U<br />
– checkPriv : U NodeID → U<br />
– incReqNo : U NodeID → U<br />
– sendReq : U NodeID → U<br />
rem<br />
l1<br />
l2<br />
l3<br />
l4<br />
– waitPriv : U NodeID Privilege → U<br />
cs<br />
– exit : U NodeID → U<br />
l6<br />
l7<br />
– completeReq : U NodeID → U<br />
– updateQueue : U NodeID → U<br />
l5<br />
procedure P1;<br />
begin<br />
requesting := true;<br />
if not have_privilege then<br />
begin<br />
rn[i] := rn[i] + 1;<br />
for all j in {1,…,N} – {i} do<br />
send request(i,rn[i]) to node j;<br />
wait until privilege(queue,ln)<br />
is received.<br />
have_privilege := true;<br />
end;<br />
Critical Section;<br />
ln[i] := rn[i];<br />
for all j in {1,…,N} – {i} do<br />
if not in(queue,j) and (rn[j] = ln[j] + 1)<br />
then queue := put(queue,j);<br />
7<br />
Quick Reminder (6)<br />
• The transitions used (cont.):<br />
– checkQueue : U NodeID → U l8 if queue ≠ empty then<br />
– transferPriv : U NodeID → U l9<br />
begin<br />
have_privilege := false;<br />
– resetReq : U NodeID → U<br />
send privilege(get(queue),ln)<br />
to node top(queue)<br />
l10 end;<br />
requesting := false<br />
– receiveReq : U NodeID Request → U end;<br />
procedure P2;<br />
begin<br />
rn[j] := max(rn[j],n);<br />
if have_privilege and not requesting and (rn[j] = ln[j] + 1) then<br />
begin<br />
have_privilege := false;<br />
send privilege(queue,ln) to node j<br />
end<br />
end;<br />
8
Data Used<br />
• Boolean values: Denoted by Bool; Specified in the built‐in module<br />
BOOL.<br />
• Natural numbers: Denoted dby Nat; Specified din the built‐in i module<br />
NAT.<br />
• Node identifiers: Denoted by NodeID; Specified in NODEID.<br />
• Queues of node identifiers: Denoted by Queue; Specified in<br />
QUEUE.<br />
• Arrays of natural numbers: Denoted by Array; Specified in<br />
ARRAY.<br />
• Requests: Denoted by Request; Specified in REQUEST.<br />
• Privileges: Denoted by Privilege; Specified in PRIVILEGE.<br />
• Messages: Denoted by Message; Specified in MESSAGE.<br />
• Multisests of messages: Denoted by Network; Specified in<br />
NETWORK.<br />
• Labels: Denoted by Label; Specified in LABEL.<br />
9<br />
Node Identifiers<br />
• Specified as follows:<br />
sort NodeID .<br />
subsorts NodeID < NzNat .<br />
op N : -> NzNat .<br />
op M : -> Nat .<br />
eq N = 2 .<br />
eq M = 2 .<br />
mb 1 : NodeID .<br />
mb 2 : NodeID .<br />
• N is the number of nodes involved.<br />
• M is the number of requests each node makes.<br />
• We suppose that there two nodes whose identifiers are 1 and 2.<br />
10
Queues of Node Identifiers<br />
• Specified as follows:<br />
sort NeQueue Queue .<br />
subsort NeQueue < Queue .<br />
op empty : -> Queue .<br />
op _|_ : NodeID Queue -> NeQueue .<br />
• The following functions are defined:<br />
– top(q) returns the top element of a non‐empty queue q.<br />
– put(q,e) puts an element e into a queue q.<br />
– get(q) delete the top element of a queue q.<br />
– e \in q checks if an element e is in a queue q.<br />
– empty?(q) checks if a queue q is empty.<br />
11<br />
Arrays of Natural Numbers<br />
• Specified as follows:<br />
sort AElm Array .<br />
subsort AElm < Array .<br />
op ia : -> Array .<br />
op _:_ : NodeID Nat -> AElm .<br />
op _,_ : Array Array -> Array [assoc comm id:<br />
ia] .<br />
• ia denotes the array, each of whose contents is 0.<br />
• i : m denotes an array slot, where i is an index and m is a content.<br />
• An array is represented as (1 : m 1 ) , … , (N : m N ).<br />
• The following functions are defined:<br />
– a[i] returns the content of an array a at the index i.<br />
– a[i] := m returns the array a’ such that a’[i] = m, and a’[j] =<br />
a[j] if j ≠ i.<br />
12
Requests and Privileges<br />
• Specified as follows:<br />
sort Request .<br />
op req : NodeID Nat -> Request .<br />
sort Privilege .<br />
op priv : Queue Array -> Privilege .<br />
• req(i,n) denotes a request that contains a node<br />
identifier i and a sequence number (natural number) n.<br />
• priv(q,ln) denotes a privilege that contains a queue<br />
q and an array ln.<br />
13<br />
Messages<br />
• Specified as follows:<br />
sort Message .<br />
op msg : NodeID Request -> Message .<br />
op msg : NodeID Privilege -> Message .<br />
• msg(i,r), where r is a request, denotes a request<br />
message addressed to node i.<br />
• msg(i,p), where p is a privilege, denotes a privilege<br />
message addressed to node i.<br />
14
Multisets of Messages<br />
• Specified as follows:<br />
subsort Message < Network .<br />
op void : -> Network .<br />
op _ _ : Network Network -> Network<br />
[assoc comm id: void] .<br />
• void denotes the empty multiset.<br />
• A multiset is represented as m 1 … m n , where each m i is a<br />
message.<br />
• The network is modeled as a multiset of messages to deal<br />
with the communication delay.<br />
15<br />
Labels<br />
• Specified as follows:<br />
sort Label .<br />
ops rem l1 l2 l3 l4 l5<br />
cs l6 l7 l8 l9 l10 : -> Label .<br />
• The constants denote the labels rem, l1, l2, l3, l4, l5,<br />
cs, l6, l7, l8, l9, and l10, respectively.<br />
16
Specification of S SK (1)<br />
• The operator corresponding to the observers:<br />
op numOfReq[_]:_ : NodeID Nat -> Obs .<br />
op pc[_]:_ : NodeID Label -> Obs .<br />
op requesting[_]:_ : NodeID Bool -> Obs .<br />
op havePriv[_]:_ : NodeID Bool -> Obs .<br />
op rn[_]:_ : NodeID Array -> Obs .<br />
op ln[_]:_ : NodeID Array -> Obs .<br />
op queue[_]:_ : NodeID Queue -> Obs .<br />
op idx[_]:_ : NodeID Nat -> Obs .<br />
op nw: _<br />
: Network -> Obs .<br />
• The number of requests each node makes is restricted in order to make the<br />
reachable state space bounded.<br />
• numOfReq[i]: m is used to record the number m of requests node i<br />
has made.<br />
17<br />
Specification of S SK (2)<br />
• The rules defining the transitions:<br />
procedure P1;<br />
begin<br />
rl [try] : (numOfReq[I]: X) (pc[I]: rem)<br />
=> (numOfReq[I]: (if X < M then X + 1 else X fi))<br />
(pc[I]: (if X < M then l1 else rem fi)) .<br />
try : U NodeID → U<br />
requesting := true;<br />
rl [setReq] : (pc[I]: l1) (requesting[I]: F)<br />
=> (pc[I]: l2) (requesting[I]: true) .<br />
setReq : U NodeID → U<br />
if not have_privilege then<br />
begin<br />
checkPriv : U NodeID → U<br />
rl [checkPriv] : (pc[I]: l2) (havePriv[I]: F)<br />
=> (pc[I]: (if F then cs else l3 fi)) (havePriv[I]: F) .<br />
18
Specification of S SK (3)<br />
• The rules defining the transitions (cont.):<br />
rn[i] := rn[i] + 1;<br />
incReqNo : U NodeID → U<br />
rl [incRecNo] : (pc[I]: l3) (rn[I]: RN) (idx[I]: X)<br />
=> (pc[I]: l4) (rn[I]: RN[I] := (RN[I]) + 1) (idx[I]: 1) .<br />
for all j in {1,…,N} – {i} do<br />
send request(i,rn[i]) to node j;<br />
sendReq : U NodeID → U<br />
rl [sendReq] : (pc[I]: l4) (idx[I]: X) (rn[I]: RN) (nw: NW)<br />
=> (pc[I]: if X == N then l5 else l4 fi)<br />
(idx[I]: if X == N then 1 else X + 1 fi) (rn[I]: RN)<br />
(nw: (if X == I then NW else msg(X,req(I,RN[I])) NW fi)) .<br />
19<br />
Specification of S SK (4)<br />
• The rules defining the transitions (cont.):<br />
wait until privilege(queue,ln) is received.<br />
have_privilege := true;<br />
waitPriv : U NodeID Privilege → U<br />
rl [waitPriv] : (pc[I]: l5) (havePriv[I]: F) (ln[I]: LN')<br />
(queue[I]: Q') (nw: (msg(I,priv(Q,LN)) NW))<br />
=> (pc[I]: cs) (havePriv[I]: true) (ln[I]: LN) (queue[I]: Q)<br />
(nw: NW) .<br />
Critical Section;<br />
rl [exit] : (pc[I]: cs) => (pc[I]: l6) .<br />
exit : U NodeID → U<br />
ln[i] := rn[i];<br />
completeReq : U NodeID → U<br />
rl [completeReq] : (pc[I]: l6) (rn[I]: RN) (ln[I]: LN)<br />
(idx[I]: X)<br />
=> (pc[I]: l7) (rn[I]: RN) (ln[I]: LN[I] := RN[I])<br />
(idx[I]: 1) .<br />
20
Specification of S SK (5)<br />
• The rules defining the transitions (cont.):<br />
for all j in {1,…,N} – {i} do<br />
if not in(queue,j) and (rn[j] = ln[j] + 1)<br />
then queue := put(queue,j);<br />
updateQueue : U NodeID → U<br />
rl [updateQueue] : (pc[I]: l7) (idx[I]: X) (rn[I]: RN)<br />
(ln[I]: LN) (queue[I]: Q)<br />
=> (pc[I]: if X == N then l8 else l7 fi)<br />
(idx[I]: if X == N then 1 else X + 1 fi)<br />
(rn[I]: RN) (ln[I]: LN)<br />
(queue[I]: if X =/= I and not(X \in Q) and<br />
(RN[X] == (LN[X]) + 1) then put(Q,X) else Q fi) .<br />
if queue ≠ empty then<br />
begin<br />
checkQueue : U NodeID → U<br />
rl [checkQueue] : (pc[I]: l8) (queue[I]: Q)<br />
=> (pc[I]: if empty?(Q) then l10 else l9 fi) (queue[I]: Q) .<br />
21<br />
Specification of S SK (6)<br />
• The rules defining the transitions (cont.):<br />
have_privilege := false;<br />
send privilege(get(queue),ln) to node top(queue)<br />
transferPriv : U NodeID → U<br />
rl [transferPriv] : (pc[I]: l9) (havePriv[I]: F) (ln[I]: LN)<br />
(queue[I]: Q) (nw: NW)<br />
=> (pc[I]: l10) (havePriv[I]: false) (ln[I]: LN) (queue[I]: Q)<br />
(nw: (msg(top(Q),priv(get(Q),LN)) NW)) .<br />
requesting := false<br />
end;<br />
rl [resetReq] : (pc[I]: l10) (requesting[I]: F)<br />
=> (pc[I]: rem) (requesting[I]: false) .<br />
resetReq : U NodeID → U<br />
22
Specification of S SK (7)<br />
• The rules defining the transitions (cont.):<br />
procedure P2; begin<br />
rn[j] := max(rn[j],n);<br />
if have_privilege and not requesting and (rn[j] = ln[j] + 1) then<br />
begin<br />
have_privilege := false;<br />
send privilege(queue,ln) to node j<br />
end<br />
end;<br />
receiveReq : U NodeID Request → U<br />
crl [receiveReq] : (requesting[I]: F) (havePriv[I]: F')<br />
(rn[I]: RN) (ln[I]: LN) (queue[I]: Q)<br />
(nw: (msg(I,req(J,X)) NW))<br />
=> (requesting[I]: F) (havePriv[I]: if C then false else F' fi)<br />
(rn[I]: RN[J] := Max) (ln[I]: LN) (queue[I]: Q)<br />
(nw: if C then (msg(J,priv(Q,LN)) NW) else NW fi)<br />
if I =/= J /\<br />
Max := if (RN[J]) < X then X else RN[J] fi /\<br />
C := F' and not(F) and Max == (LN[J]) + 1 .<br />
23<br />
Model Checking (1)<br />
• The state predicates defined:<br />
eq (pc[I]: l5) S |= wait(I) = true .<br />
eq (pc[I]: cs) S |= crit(I) = true .<br />
eq (nw: (msg(I,P) NW)) S |= existPriv(I) = true .<br />
eq (nw: (msg(I,req(J,X)) NW)) S<br />
|= existReq(I,J) = true .<br />
eq S |= PR = false [owise] .<br />
• wait(i) holds if node i is at label l5 where node i waits for receiving a<br />
privilege message.<br />
• crit(i) holds if node i is at label cs, namely that node i is in its critical<br />
section.<br />
• existsPriv(i) holds if there exists a privilege message addressed to<br />
node i in the network.<br />
• existsReq(i,j) holds if there exists a request message addressed to<br />
node i from node j in the network.<br />
24
Model Checking (2)<br />
• Properties to be checked:<br />
eq mutex = [] ~(crit(1) /\ crit(2)) .<br />
eq lofree = (wait(1) (1) |-> crit(1))<br />
/\ (wait(2) |-> crit(2)) .<br />
eq fairness = (existPriv(1) |-> ~(existPriv(1)))<br />
/\ (existReq(1,2) |-> ~(existReq(1,2)))<br />
/\ (existPriv(2) |-> ~(existPriv(2)))<br />
/\ (existReq(2,1) |-> ~(existReq(2,1))) .<br />
• mutex expresses the mutual exclusion property.<br />
• lofree eeexpresses esses the lockout out freedom property. popety<br />
• fairness expresses the fairness assumption used to check lofree,<br />
which says that every message in the network will be eventually delivered<br />
to its destination.<br />
25<br />
Model Checking (3)<br />
• The initial state when we suppose that two processes are<br />
involved:<br />
eq node(I) = (numOfReq[I]: 0)<br />
(pc[I]: rem)<br />
(requesting[I]: false)<br />
(havePriv[I]: (I == 1))<br />
(rn[I]: ia)<br />
(ln[I]: ia)<br />
(queue[I]: empty)<br />
(idx[I]: 1) .<br />
eq init = node(1) node(2) (nw: void) .<br />
26
Model Checking (4)<br />
• Checking the mutual exclusion property:<br />
red in SK-CHECK :<br />
modelCheck(init,mutex) .<br />
Maude returns true.<br />
• Checking the lockout freedom property:<br />
red in SK-CHECK :<br />
modelCheck(init,(fairness -> lofree)) .<br />
Maude returns a counterexample.<br />
27<br />
• The counterexample:<br />
A se quence of transitions lea ding to the loop<br />
Model Checking (5)<br />
counterexample({nw: void … (pc[1]: rem) (pc[2]: rem)<br />
(requesting[1]: false) (requesting[2]: false)<br />
(havePriv[1]: true) (havePriv[2]: false) …,'try}<br />
{nw: msg(1, req(2, 1)) … (pc[1]: l10) (pc[2]: l5)<br />
(requesting[1]: true) (requesting[2]: true)<br />
(havePriv[1]: true) (havePriv[2]: false) …,'receiveReq}<br />
{nw: void … (pc[1]: l10) (pc[2]: l5)<br />
(requesting[1]: true) (requesting[2]: true)<br />
(havePriv[1]: true) (havePriv[2]: false) …,'resetReq},<br />
{nw: void … (pc[1]: rem) (pc[2]: l5)<br />
(requesting[1]: false) (requesting[2]: true)<br />
(havePriv[1]: true) (havePriv[2]: false) …,'try} )<br />
Node 1 will never transfer the privilege to node 2 because node 1 receives the<br />
request message at l10 in the final (2 nd ) call of procedure P1.<br />
28
Model Checking (6)<br />
• A possible modification is that each node does not receive any<br />
request messages when it is at label l10.<br />
• The rule receiveReq is modified d as follows:<br />
crl [receiveReq] : (pc[I]: L) (requesting[I]: F)<br />
(havePriv[I]: F') (rn[I]: RN) (ln[I]: LN) (queue[I]: Q)<br />
(nw: (msg(I,req(J,X)) NW))<br />
=> (pc[I]: L) (requesting[I]: F)<br />
(havePriv[I]: if C then false else F' fi)<br />
(rn[I]: RN[J] := Max) (ln[I]: LN) (queue[I]: Q)<br />
(nw: if C then (msg(J,priv(Q,LN)) NW) else NW fi)<br />
if I =/= J /\ L =/= l10 /\<br />
Max := if (RN[J]) < X then X else RN[J] fi /\<br />
C := F' and not(F) and Max == (LN[J]) + 1 .<br />
• Maude still returns a counterexample for the lockout freedom<br />
property.<br />
29<br />
A sequence of transitions<br />
le eading to<br />
• The counterexample:<br />
counterexample(<br />
Model Checking (7)<br />
{nw: msg(1, req(2, 1)) … (pc[1]: l8) (pc[2]: l5)<br />
(requesting[1]: true) (requesting[2]: true)<br />
(havePriv[1]: true) (havePriv[2]: false) …,'receiveReq}<br />
{nw: void … (pc[1]: l8) (pc[2]: l5)<br />
(requesting[1]: true) (requesting[2]: true)<br />
(havePriv[1]: true) (havePriv[2]: false) …,'checkQueue}<br />
the loop<br />
{nw: void … (pc[1]: rem) (pc[2]: l5)<br />
(requesting[1]: false) (requesting[2]: true)<br />
(havePriv[1]: true) (havePriv[2]: false) …,'try})<br />
What is wrong is that node 1 receives the request message at l8 in the final (2 nd )<br />
call of procedure P1.<br />
30
Model Checking (8)<br />
• A possible modification is that each node does not receive any<br />
request messages either when it is at label l8.<br />
• The rule receiveReq is modified d as follows:<br />
crl [receiveReq] : (pc[I]: L) (requesting[I]: F)<br />
(havePriv[I]: F') (rn[I]: RN) (ln[I]: LN) (queue[I]: Q)<br />
(nw: (msg(I,req(J,X)) NW))<br />
=> (pc[I]: L) (requesting[I]: F)<br />
(havePriv[I]: if C then false else F' fi)<br />
(rn[I]: RN[J] := Max) (ln[I]: LN) (queue[I]: Q)<br />
(nw: if C then (msg(J,priv(Q,LN)) NW) else NW fi)<br />
if I =/= J /\ L =/= l10 /\ L =/= l8 /\<br />
Max := if (RN[J]) < X then X else RN[J] fi /\<br />
C := F' and not(F) and Max == (LN[J]) + 1 .<br />
• Maude still returns a counterexample for the lockout freedom<br />
property.<br />
31<br />
A sequence of transitions<br />
le eading to<br />
• The counterexample:<br />
counterexample(<br />
Model Checking (9)<br />
{nw: msg(2, req(1, 1)) … (pc[1]: l5) (pc[2]: l7)<br />
(requesting[1]: true) (requesting[2]: true)<br />
(havePriv[1]: false) (havePriv[2]: true) …,'receiveReq}<br />
{nw: void … (pc[1]: l5) (pc[2]: l7)<br />
(requesting[1]: true) (requesting[2]: true)<br />
(havePriv[1]: false) (havePriv[2]: true) …,'updateQueue}<br />
the loop<br />
{nw: void … (pc[1]: l5) (pc[2]: rem)<br />
(requesting[1]: true) (requesting[2]: false)<br />
(havePriv[1]: false) (havePriv[2]: true …,'try})<br />
What is wrong is that node 2 receives the request message at l7 in the final (2 nd )<br />
call of procedure P1.<br />
32
Model Checking (8)<br />
• A possible modification is that each node does not receive any<br />
request messages either when it is at label l7.<br />
• The rule receiveReq is modified d as follows:<br />
crl [receiveReq] : (pc[I]: L) (requesting[I]: F)<br />
(havePriv[I]: F') (rn[I]: RN) (ln[I]: LN) (queue[I]: Q)<br />
(nw: (msg(I,req(J,X)) NW))<br />
=> (pc[I]: L) (requesting[I]: F)<br />
(havePriv[I]: if C then false else F' fi)<br />
(rn[I]: RN[J] := Max) (ln[I]: LN) (queue[I]: Q)<br />
(nw: if C then (msg(J,priv(Q,LN)) NW) else NW fi)<br />
if I =/= J /\ L =/= l10 /\ L =/= l8 /\ L =/= l7 /\<br />
Max := if (RN[J]) < X then X else RN[J] fi /\<br />
C := F' and not(F) and Max == (LN[J]) + 1 .<br />
• Maude returns true for the lockout freedom property.<br />
33