12.03.2014 Views

lectureNote8

lectureNote8

lectureNote8

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!