# Inv: ready -> msg bool ready = false buffer msg co while ready msg = data ; ready = true || while !ready ; f(msg) ; ready = false
msg
and then writes writes
.
msg
and then writes empty
.
while ready int t = ready msg = data while t ready = true msg = data ready = true while !ready while !ready f(msg) ready = false ready = false f(msg)
msg3 = data3 msg3 = data3 msg2 = data2 msg2 = data2 msg0 = data0 ready = true msg1 = data1 msg1 = data1 ready = true msg0 = data0
Thread.VolatileRead(T &)
does an acquire.
Thread.VolatileWrite(T &)
does a release.
T
is a primitive type (byte, int, double, or object reference).
System.Threading.Thread.MemoryBarrier()
.
BigExpensiveObject beo = new BigExpensiveObject() // beo may or may not read.
BigExpensiveObject beo = null if beo == null beo = new BigExpensiveObject() // read beo
beo
also have to check for initialization.
beo
is shared?
beo
is (almost) read-only; we (almost) don't care.
mutex.lock() if beo == null beo = new BigExpensiveObject() mutex.unlock() // read beo
beo
is atomic.
if beo == null mutex.lock() if beo == null beo = new BigExpensiveObject() mutex.unlock() // read beo
beo
need to be volatile?
beo
could precede field writes.
bdo != null
with uninitialized fields.
beo
is an implicit synchronization lock between
initializer and reader.
System.Threading.Interlocked
provides four atomic operations:
T Increment(T & x) < return x++ > T Decrement(T & x) < return --x > T Exchange(T & x, T Y) < T t = x ; x = y ; return t > T CompareExchange(T & x, T y, T z) < T t = x ; if (x == z) x = y ; return t >
beo
with one of these operators.
BigExpensiveObject()
is
idempotent and side-effect free.
This page last modified on 5 August 2003.