----------------------------------------------------------------------------- Mohamed G. Gouda CS 356 Summer 2009 Homework 1 ----------------------------------------------------------------------------- 1. (7 points) The processes in a process array p[i: 0..n-1] are arranged in a uni-directional ring where there is a channel from each process p[i] to the next process p[i +n 1]. The data structure of each process in this array is as follows: const g, t inp grp : 0..g-1 var rcvd: array [integer] of 0..t-1, x : integer, {index of rcvd, init. 0} r : 0..g-1, txt : 0..t-1 The input grp in each process p[i] indicates the group to which p[i] belongs. At each instant, each process p[i] can generate a data(r, txt) message where r is the group to which p[i] belongs and txt is the message text. Each generated data(r, txt) message circulates around the ring until the txt field of the message is stored in array rcvd of every process that belongs to group r. The processes p[0..n-1] are designed such that, for each j, the final values of elements rcvd[j] in all processes, that belong to the same group, are identical. To achieve this goal, the txt field of any generated data(r, txt) message is not stored in any rcvd array until the message reaches process p[0], which transforms the message to a store(r, txt) message. This design requires that the actions of process p[0] be different from the actions of any of the other processes p[i : 1..n-1]. i. Specify the actions of process p[0]. ii. Specify the actions of process p[i : 1..n-1]. Assume that the communications between the processes are error-free. Solution: process p[0] const g, t inp grp : 0..g-1 var rcvd: array [integer] of 0..t-1 x : integer, {index of rcvd, init. 0} r : 0..1, txt : 0..t-1 begin true -> txt:=any; rcvd[x],x:=t,x+1; send store(grp,txt) to p[1] [] rcv data(r,txt) from p[n-1] -> if grp=r -> rcvd[x],x:=txt,x+1 [] grp!=r -> skip fi; send store(r,txt) to p[1] end process p[i:1..n-1] {n>=2} const g, t inp grp : 0..g-1 var rcvd: array [integer] of 0..t-1, x : integer, {index of rcvd, init. 0} r : 0..1, txt : 0..t-1 begin true -> txt:=any; send data(grp,txt) to p[i +n 1] [] rcv data(r,txt) from p[i -n 1] -> send data(r,txt) to p[i +n 1] [] rcv store(r,txt) from p[i -n 1] -> if grp=r -> rcvd[x],x:=txt,x+1 [] grp!=r -> skip fi; if i send store(r,txt) to p[i +n 1] [] i=n-1 -> skip fi end ----------------------------------------------------------------------------- 2. (3 points) Consider the protocol that involves the following three processes p, q, and r: process p const t var ready : boolean, {init. true} txt : 0..t-1 begin ready --> ready, txt := false, any; send data(txt) to q [] rcv ack from q --> ready := true [] rcv nack from q --> send data(txt) to q [] rcv error from q --> send data(txt) to q end process q const t var txt : 0..t-1 begin rcv data(txt) from p --> send data(txt) to r; send ack to p [] rcv error from p --> send nack to p end process r const t var txt : 0..t-1 begin rcv data(txt) from q --> {store txt} skip end Assume that the channels between p and q can corrupt and reorder (but not lose) messages. Assume also that the channel from q to r is error-free. Is there a problem concerning the end-to-end transfer of data from process p to process r? Explain your answer. Solution: Process r can end up receiving two or more copies of the same data message sent by process p. (But r does receive at least one copy of each message sent by p. Moreover, r receives the messages in order.) -------------------------------------------------------------------------------