Programming Assignment VII

Due on Friday, April 16, 2004 @ 11pm

60 points

Leader Election in a Ring Network

In a distributed system, processes running on different networked computers must coordinate with each other to carry out some tasks. However, some programming tasks such as system initialization can only be done by exactly one process. One might dedicate a specific process to do this unique task; however, we also prefer to have a "uniform" structure so that every involved process would be essentially "identical." If this is the case, when that unique task is needed, all involved processes must elect a leader and let the leader perform the unique task. This is the concept of Leader Election or simply Election. This programming assignment tells you how a leader can be elected easily if all involved processes are run in a ring network and communicate with asynchronous channels.

An unidirectional ring network consists of n processes P0, P1, ..., Pn-1, and a channel from Pi and Pi+1 for 0 <= i < n-1 and a channel from Pn-1 to P0 as shown below. Furthermore, suppose process Pi has a user identifier UIDi. The way of electing a leader from these n processes is actually very simple. We just elect the process with the largest UID! The problem is that each process only knows its own UID and its two neighbors. Thus, message passing is needed to find out if a process has the largest UID and let it continue with the unique task.

When the leader election procedure starts, every process sends its UID to its neighbor (i.e., from Pi to Pi+1 for 0 <= i < n-1, and from Pn-1 to P0). Upon receiving a message, process Pi examines the content of the message:

  1. If the message is larger than Pi's UID, Pi sends the received message to its neighbor.
  2. If the message is smaller than Pi's UID, Pi does nothing and the message is ignored since it will not be circulated.
  3. If the message is equal to Pi's UID, then Pi is the leader.
Pi repeats the above steps until it is blocked by the message wait operation because no more message is circulated. Otherwise, Pi is the leader.

Program Specification

Please note the following specifications. Without observing these rules, you will risk lower grades.
  1. Each process is simulated with a thread like the following:
    send its own UID; 
    while (not done) {
         receive a message;
         compare the incoming message;
         kill it, or pass it to neighbor;
         or, announce "I am the leader" and I am done
    }
    
    Once a process finds out it is the leader, it starts to circulate the END message. Each non-leader process exits upon receiving this END message. When the END message comes back to the leader, the leader exits! Since process indices and UID's are all non-negative integers, you may choose -1 for the END message.
  2. You program should not use any global variable, because in a distributed system there is no global data. More precisely, when a thread is created, it has all needed information as local data and should not access any global data (if there is any -- perhaps created by the main program). If you use any global variables in your program, you will receive no credit.
  3. Between receiving an incoming message and sending it to a neighbor, you should use the Delay() method to generate a random delay.
  4. In your program, you should only use asynchronous channels for building the communication links between threads.
  5. Your programs should use 0, 1, 2, 3, ..., n-1 as user defined IDs for channel building. However, n should not be known by any thread. The UID of a process should be a random integer that is only known to a single thread, initially.
  6. When it is created, a thread should receive i (the index in Pi), UID (a random integer generated and passed by the main program), its incoming channel, and its outgoing channel. All channels are built before threads are created. It is not difficult for process Pi to know the process IDs of its predecessor and successor. Since ThreadMentor channels are bi-directional, Pi can send its process ID to its neighbors, and, as a result, you do not have problem in printing out i-1 and i+1. After this information has been communicated with its neighbors, Pi starts the leader election computation.

Input and Output

There is no input file. The number of processes in a ring network should be taken from a command line argument. Name the executable of your program as prog7. It accepts one command line argument n, indicating the number of processes. You can assume the value of n is always larger than or equal to 3. If there is no command line argument, the default value is 5.

The output is very simple. The following is a sample.

Process 0 (UID 7369) started
    Process 2 (UID 3469) started
  Process 1 (UID 9742) started
     ..........
  Process 1 (UID 9742) sends 9742 to process 2
    Process 2 (UID 3469) sends 3469 to process 3
     ..........
  Process 1 (UID 9742) receives 7369 from process 0
    Process 2 (UID 3469) receives 9742 from process 1
     ..........
  Process 1 (UID 9742) kills incoming message 7369
    Process 2 (UID 3469) passes 9742 to process 1
     ..........
  Process 1 (UID 9742) receives 9742 from process 0
        ..........
  Process 1 (UID 9742) is the leader!
  Process 1 (UID 9742) starts to circulate END
     ..........
Process 0 (UID 7369) receives END and terminates
     ..........
  Process 1 (UID 9742) receives END and terminates
     ..........
FROM MAIN: Leader Election done.
Here are some notes:
  1. Output from process i has an indentation of 2i spaces.
  2. After a process receives an incoming message, the content of this message must be shown as follows:
    Process 1 (UID 9742) receives 7369 from process 0
    
    This shows process 1 with UID 9742 receives a message 7369 from process 0.
  3. After a process sends a message to its neighbor, the following must be displayed:
    Process 2 (UID 3469) sends 3469 to process 3
    
    This shows process 2 with UID 3469 sends a message 3469 to its neighbor process 3.
  4. A process may kill an incoming message:
    Process 1 (UID 9742) kills incoming message 7369
    
    This shows process 1 with UID 9741 kills the incoming message 7369.
  5. Finally, once a leader is elected, your program must report this event as follows:
    Process 1 (UID 9742) is the leader!
    
    This shows process 1 is the leader.
  6. Just a reminder: The UIDs must be generated within your program using random number generator. They cannot be part of the input or fixed in your program.

Submission Guidelines

  1. All programs must be written in ANSI C or C++ using ThreadMentor.
  2. Use the submit command to submit your work. You can submit as many times as you want, but only the last one will be graded. A makefile is required. Name your executable prog7.
  3. I will use the following approach to compile and test your programs:
    make              <-- make your program
    prog7  10         <-- test your program
    
    I may repeat the above procedure several times to see if your program performs correctly.
  4. Your implementation should fulfill the program specification as stated. Any deviation from the specification will cause you to receive zero point.
  5. You should aim for maximum parallelism. That is, implement the solution as stated and make sure all required threads will execute simultaneously. Without doing so, you risk very low grade.
  6. No late submission will be graded.
  7. My rule of grading is deduction based. I assume you always receive 100%. If you missed something, some points will be taken off based on the following rules. Read these rules carefully. Otherwise, you could receive low or very low grade. Click here to see how your program will be graded.
  8. Since the rules are all clearly stated above, no leniency will be given. So, if you have anything in doubt, please ask for clarifications.