Enforcing Mutual Exclusion Message Passing
Peterson’s Algorithm for Processes P0 and P1 void P0() { while( true ) { flag[ 0 ] = false; /* remainder */ flag[ 0 ] = true; turn = 1; while( flag[ 1 ] && turn == 1 ) { /* do nothing */ } /* critical section */ } } void P1() { while( true ) { flag[ 1 ] = false; /* remainder */ flag[ 1 ] = true; turn = 0; while( flag[ 0 ] && turn == 0 ) { /* do nothing */ } /* critical section */ } } 2
Peterson’s Algorithm for Processes P1 and P2 void P1() { while( true ) { flag[ 1 ] = false; /* remainder */ flag[ 1 ] = true; turn = 2; while( flag[ 2 ] && turn == 2 ) { /* do nothing */ } /* critical section */ } } void P2() { while( true ) { flag[ 2 ] = false; /* remainder */ flag[ 2 ] = true; turn = 1; while( flag[ 1 ] && turn == 1 ) { /* do nothing */ } /* critical section */ } } 3
Peterson’s Algorithm – Generalizing the “flag” variable void P1() { while( true ) { stage[ 1 ] = 0; /* remainder */ stage[ 1 ] = 1; turn = 2; while( stage[ 2 ] >= 1 && turn == 2 ) { /* do nothing */ } stage[ 1 ] = 2; /* critical section */ } } void P2() { while( true ) { stage[ 2 ] = 0; /* remainder */ stage[ 2 ] = 1; turn = 1; while( stage[ 1 ] >= 1 && turn == 1 ) { /* do nothing */ } stage[ 2 ] = 2; /* critical section */ } } 4
Peterson’s Algorithm – Generalizing the “turn” variable void P1() { me = 1; while( true ) { stage[ me ] = 0; /* remainder */ stage[ me ] = 1; polite[ 1 ] = me; while( stage[ 2 ] >= 1 && polite[ 1 ] == me ) { /* do nothing */ } stage[ me ] = 2; /* critical section */ } } void P2() { me = 2; while( true ) { stage[ me ] = 0; /* remainder */ stage[ me ] = 1; polite[ 1 ] = me; while( stage[ 1 ] >= 1 && polite[ 1 ] == me ) { /* do nothing */ } stage[ me ] = 2; /* critical section */ } } 5
Peterson’s Algorithm for Process P2 of P1, P2, and P3 void P2() { me = 2; while( true ) { stage[ me ] = 0; /* remainder */ stage[ me ] = 1; polite[ stage[ me ] ] = me; while( stage[ 1 ] >= stage[ me ] && polite[ stage[ me ] ] == me ) { /* do nothing */ } while( stage[ 3 ] >= stage[ me ] && polite[ stage[ me ] ] == me ) { /* do nothing */ } stage[ me ] = 2; polite[ stage[ me ] ] = me; while( stage[ 1 ] >= stage[ me ] && polite[ stage[ me ] ] == me ) { /* do nothing */ } while( stage[ 3 ] >= stage[ me ] && polite[ stage[ me ] ] == me ) { /* do nothing */ } stage[ me ] = 3; /* critical section */ } } 6
Message Passing Enforce mutual exclusion Exchange information send (destination, message) receive (source, message) 7
Design issues 8 Synchronization Type of Addressing Format of message Queuing discipline
Synchronization Sender and receiver each may be blocking or nonblocking Blocking send, blocking receive Both sender and receiver are blocked until message is delivered Called a rendezvous Nonblocking send, blocking receive Sender continues on Receiver is blocked until the requested message arrives Nonblocking send, nonblocking receive Neither party is required to wait 9
Addressing Direct addressing Send primitive Includes a specific identifier of the destination process Receive primitive could Know ahead of time from which process a message is expected Use source parameter to return a value when the receive operation has been performed Indirect addressing Mailboxes Messages are sent to a shared data structure Data structure consists of one or more queues Queues are called mailboxes Sender “drops off” a message at the appropriate mailbox Receiver “picks up” the message from the mailbox 10
11
Message Format 12