Lecture 5
Review -- finding patterns in a file using two processes
(a) "co inside while" (b) "while inside co"
outline of code outline of code
synchronization:
(a) provided by co ... oc
(b) need to program it; today we'll see how
the requirements are alternating access and detecting termination
Example (I mix between using SR and C/book notation)
int x = 0, y = 0, z;
P1:: x = 1; P2:: y = 2;
z = x+y; z = x-y;
what are the final values of x, y, and z?
have the class help out
answer depends on execution order and what is atomic
States, Actions, etc. (Section 2.1)
state -- values of variables at a point in time
atomic action -- indivisible state change
hardware: load, store, add, ...
software: critical sections (Chapter 3)
history -- a trace of ONE execution; an interleaving of atomic actions
property -- an attribute of ALL histories of a program, e.g., correctness
today: understanding states and actions
next time: proving properties in a programming logic
How many histories are there in a program with n processes and
m atomic actions per process?
(n m)! / (m!)**n if n = 2 and m = 4, this is 70 histories!
Synchronization (Section 2.3) -- restricts the number of histories
Given array a[1:n] of positive integers
Find the maximum value m by examining all elements in parallel
[this is an example of an accumulation or reduction problem]
Goal -- expressed as a predicate
(for all j : 1 <= j <= n : m >= a[j]) and
(there exists j : 1 <= j <= n : m = a[j])
Program outline
var m := 0
process FindMax(i := 1 to n)
body
end
Program 1 for body -- no synchronization (hence no constraints)
if a[i] > m -> m := a[i] fi
what is true before and after this statement?
what is wrong with this program? (interference)
what's the most that we can say? (m is SOME a[i])
Program 2 for body -- make it a single atomic action (overconstrained)
< m -> m := a[i] fi>>
the program is now correct, but the processes are serialized
comment on the angle bracket notation
also comment on how this program is not the same as a sequential
program, because the processes could execute in any order (although
they will do so one at a time)
Program 3 for body -- use smaller atomic actions
if a[i] > m ->
< m -> m := a[i] fi>>
fi
What's true now before and after the outer if statement? Why?
This technique is called "double checking". It may not seem like
we have accomplished much, but in fact we have. We'll actually
see this technique put to realistic use later. (In fact, access
to an Ethernet works kind of like this.)
Atomic Actions (Section 2.4)
fine grained -- reads and writes of simple variables (loads/stores)
coarse grained -- programmed using << ... >> or real code (in Chap 3)
<< S; >> execute statement list S indivisibly
<< await(B); >> wait for B to be true
<< await(B) S; >> wait for B to be true, then execute S
AS A SINGLE ATOMIC ACTION
examples of the use of await statements
<< s = s+1; >>
<< await (s>0) s = s-1; >>
these are semaphore operations as many of you might recognize
at-most-once property
<< S; >> == S; as long as S contains at most one critical reference,
that is a reference to a variable changed by another process
in this case, you cannot tell the difference, so S will appear to
execute atomically
<< await(B); >> == while (not B) ; if B contains at most one
critical reference
Producer/Consumer example to put all this together (Section 2.5)
problem: copy a[n] in Producer to b[n] in Consumer using a single
shared buffer
use synchronization to alternate access to the buffer
sketch the idea of the problem and solution, then present the
code in Figure 2.2. (See figures section of these Web pages)
comment on synchronization code; mention that this specific code
can be implemented using busy waiting while loops because each
await statement contains only