Mathematics of Shared Variables
This page is about shared variable concurrency issues, using
mathematical logic. It assumes you read through the notes on assertions.
Fine Grained Atomicity
S1 :: x := y
S2 :: y := z
S0 :: co S1 || S2 oc
| |
Final value of x can be:
old-y or z
|
| | |
S1:: y := 0; z := 0
S2:: x := y + z
S3:: y := 1; z := 2
S0:: S1; co S2 || S3 oc
| |
Final value of x can be:
0, 1, 2, or 3
|
| | |
co x := y + y || y := 1 oc
|
|
has two references to y. y + y can read both the old and
new values of y in either instance.
|
| | |
|| | | Interpret as (e.g. Java) threads |
Specifying Synchronization
- The await statement ‹ await B → S › is a coarse grained
construct.
- Condition synchronization: ‹ await B ›
- Unconditional atomic action: ‹ S ›
- Conditional atomic action: ‹ await B → S ›
Is ‹ await B › implemented as do not B →
skip od correct?
-
Await Rule:
{P & B} S {Q} ⇒ {P} ‹ await B → S › {Q}
At-Most-Once(e)
-
for-all x in sharedVars(e):
(nrefs(x, e) ≤ 1)
-
Simple variable ≡ a whole variable, not a "part", e.g., array[i];
-
e is an expression of "this" process; P stands for any "other" process
-
writeVars(P) ::= vars P modifies; readVars(P) ::= vars P reads
-
sharedVars(e) ::= modified by others
-
nrefs(x, e) ::= (free) occurs of x in e
‹ await B › implemented as do not B →
skip od is correct if
At-Most-Once(B)
At-Most-Once(x := e)
-
(At-Most-Once(e) & x not-in readVars(P)) OR
(simpleVar(x) & refVars(e) disjoint-with writeVars(P))
-
writeVars(P) ::= vars P modifies, readVars(P) ::= vars P reads
- refVars(P) ::= vars P reads/writes
-
A statement using shared variables obeying the At-Most-Once
property executes as if it were atomic.
Deduction Rules
- {x = 0 & y = 0} co x := x + 1 || y := y + 1 oc {??}
x = 1? y = 1? Yes.
- Can we generalize this? Suppose {Pi} Si {Qi}. Can we then conclude
{P1 & P2 & ... & Pn} co S1 || S2 || ... || Sn oc {Q1 & Q2 &...& Qn}
?
No.   E.g.,
Si :: x := x + 1,
Pi ≡ {x = 0}, Qi ≡ {x = 1}
We have interference.
Interference, Intuitively speaking ...
- A program consisting of several processes
(threads) works "well" zillions of times, but every once in a while
it works incorrectly. Problem could be shared variable
interference.
- Consider the execution of statement Si of a chosen process.
There must be a precondition for Si (whether you bothered to write
it or not). Consider the weakest such precondition Pi. In all the
zillions of times, this Pi was True, and Si works "well".
- Suppose Pi became False because of other processes. Rarely,
ofcourse. Si no longer works "well". This is not going to be solved
by inserting Si into ‹ Si ›
- Is this going to happen with all Si? Only for certain
"important" ones.
Free of Interference
- We will identify critical assertions in the sense of "highly
important".
- We verify that these are not becoming False due to other
processes.
Critical Assertions
- Good coding: An assignment x := e executes atomically:
- At-Most-Once(x := e)
- ‹ x := e ›
- Complete proof oultine: An assertion before and after each statement.
-
{P(e)} ‹ x := e › {P(x)} P(e) is a critical assertion.
- {P} ‹ S1; {Q} S2 › {R} Q is not a critical
assertion. The state of the process after S1 is not visible to
others.
Consider the complete proof of {P} S {Q}. S
contains || and ‹ ›
- Q is a critical assertions, and
- for each statement T within S that is not
within an await statement,
{pre(T)} T {post(T)}, the
weakest predicate pre(T) is a critical assertions.
Non-Interference
- Assignment action A. Critical assertion C.
- A does not interfere with C, NI(A, C), if {C & pre(A)} A {C}.
Interference Freedom
{Pi} Si {Qi}, 1 ≤ i ≤ n,
are interference-free if
for-all A in Si
for-all C in Sj, i ≠ j,
NI(A, C) holds.
|
|
Concurrency Rule
{Pi} Si {Qi}, 1 ≤ i ≤ n, are interference-free
⇒
{P1 & ... & Pn}
co S1 || S2 || ... || Sn oc
{Q1 & ... & Qn}
|
Avoiding Interference
- #histories of a conc program is exponential in #atomic-actions
- #ways of interferences is much smaller
- Disjoint Variables:
(writeVars(P1) disjoint refVars(P2) & writeVars(P2) disjoint refVars(P1))
implies P1 and P2 do not interfere.
Weakened Assertions-1
Concurrency Rule is sufficient, but not necessary. E.g., we can
intuitively see that x = 3 after S0 in the following.
X0:: x := 0
S1:: ‹ x := x + 1 ›
S2:: ‹ x := x + 2 ›
S0:: X0; co S1 || S2 oc
| |
Clearly, post S0 we have x = 3. But, with
{x = 0} S1 { x = 1}
{x = 0} S2 { x = 2}
valid (in isolation), that x = 3 cannot be proven.
S1 interferes with x = 0, and x = 2.
S2 interferes with x = 0, and x = 1.
|
Weakened Assertions-2
X0:: x := 0
S1:: ‹ x := x + 1 ›
S2:: ‹ x := x + 2 ›
S0:: X0; co S1 || S2 oc
| |
We can show, using the rules we have so far,
{(x = 0 or x = 1) & (x = 0 or x = 2)}
co S1 || S2 oc
{(x = 2 or x = 3) & (x = 1 or x = 3)}
Pre- simplifies to x = 0. Post- simplifies to x = 3.
|
- Even when writeVars(P) overlap refVars(P), there may not be
interference.
- The "Weekened Assertion" method is for this situation.
About shared variables, make a weaker assertion than could be
made if processes were executed in isolation.
Weakened Assertions-3
weaken {x = 0} S1 { x = 1} to {x = 0 or x = 2} S1 { x = 1 or x = 3}
weaken {x = 0} S2 { x = 2} to {x = 0 or x = 1} S2 { x = 2 or x = 3}
Claim: S1 does not interfere with pre(S2).
Proof:
Show NI(S1, pre(S2)) holds.
- i.e., show {pre(S2) & pre(S1)} S1 {pre(S2)}.
- i.e., show {(x = 0 or x = 1) & (x = 0 or x = 2)} S1 {(x = 0 or x = 1)} holds.
- i.e., show {x = 0} S1 {(x = 0 or x = 1)} holds.
- i.e., show (x = 0) ⇒ (x+1 = 0 or x+1 = 1) holds.
- i.e., show (x = 0) ⇒ (x = -1 or x = 0) holds. QED
Weakened Assertions-4
Claim: S2 does not interfere with pre(S1).
Proof: similar
Now, we can instantiate the Concurrency Rule
{x = 0 or x = 2} S1 { x = 1 or x = 3}
{x = 0 or x = 1} S2 { x = 2 or x = 3}
no interference
⇒
{(x = 0 or x = 2) & (x = 0 or x = 1)} co S1 || S2 oc {(x = 1 or x = 3) & (x = 2 or x = 3)}
The above simplifies to
{x = 0} co S1 || S2 oc {x = 3}
Global Invariants
- An assertion I is a global invariant if it is true (i) before the
processes begin, and (ii) before and after every assignment action of all
processes.
-
{I & pre(a)} a {I}, for all a taken from all processes.
- C ≡ I & L, where C is a critical assertion of Pj and L an
assertion about private/local variables of Pj.
- If all assertions are of the above form, the processes are
interference-free.
- Study the proof of the Array Copy from Andrews book.
Synchronization
- co P1:: ... {pre(a)} a ...
|| P2:: ... S1; {C} S2 ...
oc
Suppose a interferes with critical assertion C.
- Solution-1: Hide C from a, using mutex in P2: ‹ S1; S2
›
- Solution-2: Replace a of P1 with ‹ await not C or
wp(a, C) → a ›
Auxiliary Variables-1
- Program counters of different processes
- Introduce aux vars solely for proof purposes.
-
Suppose S' has aux variables. S is S1 with all statements using aux
vars deleted. Suppose P, Q are assertions about regular vars. Then,
{P} S' {Q} ⇒ {P} S {Q}
Auxiliary Variables-2
var x := 0; var t1 := 0; var t2 := 0; {Let I ≡ x = t1 + t2}
{I & t1 = 0 & t2 = 0}
co {I & t1 = 0} ‹ x := x+1; t1 := 1 › {I & t1 = 1}
|| {I & t2 = 0} ‹ x := x+1; t2 := 1 › {I & t2 = 1}
oc
{I & t1 = 1 & t2 = 1}
Each assertion is an & of a global invariant and an assertion on vars
not used by the other process. The above is interference-free. Thus,
the above is a valid conclusion.
Proving Safety Properties
- See temporal logic for defs
of safety and liveness.
- To prove that an assertion F is a safety property of a program
G, show that
every C ⇒ F, where C are critical assertions from
{P} G {Q}
- Our phrasing above differs from Andrews for th ebetter.
- Exclusion of Configs. Suppose P & Q is false. A process
cannot then be in a state satifying P when/while another process is
in a state statisfying Q.
Liveness and Fairness
- Most liveness properties depend on fairness. See fairness-etc.
- See temporal logic for defs
of weak and strong fairness.
Exercises
-
See the Exercises in Andrews, Chapters 1 and 2.
- Does the precondition and statement {x ≥ 4 } ‹ x := x - 4
› interfere with the triple
{x is odd} ‹ x := x + 5 › {x is even}.
- Using the technique of weakened assertions, prove that {x = 1}
S {x = 7} is a theorem, where S is co ‹ x := x+1›
|| ‹ x := x+2› || ‹ x := x+3› oc
References
- Gregory R. Andrews, Concurrent Programming: Principles and
Practice, Benjamin/Cummings, 1991. Chapters 1 and 2:
Required Reading.
- Mark Batty, Scott Owens, Susmit Sarkar, Peter Sewell, and Tjark
Weber, Mathematizing C++ Concurrency, ACM POPL 2011. Web-search
for its pdf. Recommended Reading.