CMSC 412 |
NOTE 8 |
March 16, 1999 |
boolean test_and_set( memoryBit target ) { returns old value of target and sets target to true }
boolean swap( memoryBit a, b ) { swaps the values of a and b }
// variables shared by processes 0, 1, ..., N-1 boolean lock initially FALSE entry(i) { while test_and_set( lock ) do skip ; // at most one process comes here } exit(i) { lock := FALSE ; }The above program satisfies the safety property but not the progress property (because we still cannot assume anything about process speeds other than that it is non-zero).
// variables shared by processes 0, 1, ..., N-1 boolean lock initially FALSE entry(i) { boolean key := TRUE ; repeat swap( key, lock ) until key=FALSE ; } exit(i) { lock := FALSE ; }
// variables shared by processes 0, 1, ..., N-1 boolean lock initially FALSE ; // read/writeable by all processes boolean waiting[0..N-1] initially FALSE ; // read/writeable by all processes entry(i) { boolean key := TRUE ; waiting[i] := TRUE ; while ( waiting[i] and key ) do { key := test_and_set( lock ) ; }; waiting[i] := FALSE ; } exit(i) { int p ; // search for next waiting process p := (i+1) mod N ; while ( p != i and not waiting[p] ) do { p := (p+1) mod N ; }; if p=i then { lock := FALSE } // no waiting proceses else { waiting[p] := FALSE } // p is next waiting process. Free it }In entry(i), the while-loop test succeeds (and hence process i busy waits) if and only if the lock is already false (i.e., grabbed by another process) and this process is waiting. So a process j that has grabbed the lock can give it to process i by setting waiting[i] to false.