Silly question about IORefs and MVars
Alastair Reid
alastair@reid-consulting-uk.ltd.uk
23 Nov 2002 13:48:03 +0000
Nicolas Oury <Nicolas.Oury@ens-lyon.fr> writes:
> I wonder why IORefs updates aren't safe : it seems that preemptive
> scheduling takes place during memory allocation and I can't see
> where there could be an allocation (and so a switch) in a read or a
> write of an IORef.
Here's a typical code sequence:
foo rx = do
x <- readIORef rx
writeIORef rx (x+1)
but GHC will 'desugar' this code to:
foo rx = do
x <- readIORef rx
let x' = (+) x 1 -- build a thunk
writeIORef rx x'
Building thunks allocates memory which can cause context switches so
foo does not execute atomically.
Simpler code which merely swaps the current value for a new value
would seem to be immune to such problems but then you have to figure
that 'do' expressions are merely syntactic sugar for a bunch of calls
to >>= and >>. These might allocate memory.
And, finally, it's possible that writeIORef is, somehow, a thunk. For
example, writeIORef used to have a different name like writeRef or
writeIOVar or some such. The easiest way to rename this variable
would be to write:
writeIORef = writeRef
So, when you call writeIORef you might cause evaluation of a thunk.
Evaluating thunks can allocate memory.
--
Alastair Reid
ps It's best to avoid relying on compilers not to context switch at
particular times unless it is documented that this is a property you
can rely on. That kind of reasoning tends to break down when your
compiler gets smarter or you switch compilers or...