12.03.2014 Views

lectureNote8

lectureNote8

lectureNote8

SHOW MORE
SHOW LESS

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

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

Saved successfully!

Ooh no, something went wrong!