3.3 KiB
Critical sections (locks) have drawbacks:
- if not put at the right level of granularity, they unnecessarily reduce concurrency
- delays of one process may affect the whole system
MUTEX-freedom: the only atomicity is the one provided by the primitives themselves (no wrapping of code into CSs) the liveness properties used so far cannot be used anymore, since they rely on CSs. (example: if we have only atomic R/W registers, these are the only atomic things that we have. But we may also have atomic primitives like test&set, compare&swap ecc.).
Liveness properties
We have four new liveness properties
- Obstruction freedom: every time an operation is run in isolation (no overlap with any other operation on the same object), it terminates
- Non-blocking: whenever an operation is invoked on an object, eventually one operation on that object terminates
- reminds deadlock-freedom in MUTEX-based concurrency
- Wait freedom: whenever an operation is invoked on an object, it eventually terminates
- reminds starvation-freedom in MUTEX-based concurrency
- Bounded wait freedom: wait freedom + a bound on the number of steps needed to terminate
- reminds bounded bypass in MUTEX-based concurrency
REMARK: these notions naturally cope with (crash) failures. Fail stop is another way of terminating, there is no way of distinguishing a failure from an arbitrary long sleep (because of asynchrony).
A wait-free Splitter
Assume we have atomic R/W registers.
A splitter is a concurrent object that provides a single operation dir such that:
- (validity) it returns L, R or S (left, right, stop)
- (concurrency) in case of n simultaneous invocations of dir
- at most n-1 L are returned
- at most n-1 R are returned
- at most 1 S is returned
- (wait freedom) it eventually terminates.
Idea:
- not all processes obtain the same value
- in a solo execution (i.e., without concurrency) the invoking process must stop (0 L && 0 R && at most 1 S)
We have:
- DOOR: MRMW boolean atomic register initialized at 1
- LAST: MRMW atomic register initialized at whatever process index
dir(i) :=
LAST <- i
if DOOR = 0 then
return R
else
DOOR <- 0
if LAST = i then
return S
else
return L
With 2 processes, we can have:
- one goes left and one goes right
- one goes left and the other stops
- one goes right and the other stops
Soundness theorem
this implementation satisfies the three requirements for the splitter
Proof:
- Not all processes can obtain R
- the door must have been closed and who closed the door cannot obtain R
- not all processes can obtain L
- let us consider the last process that writes into LAST (this is an atomic register, so this is meaningful)
- if the door is closed, it receives R and √
- let
p_i
be the first process that receivesS \to LAST=i
in its second if !
An Obstruction-free Timestamp Generator
A timestamp generator is a concurrent object that provides a single operation get_ts such that:
- (validity) not two invocations of get_ts return the same value
- (consistency) if one process terminates its invocation of get_ts before another one starts, the first receives a timestamp that is smaller than the one received by the second one
- (obstruction freedom) if run in isolation