No atomic read on MVar?

Philip K.F. Hölzenspies p.k.f.holzenspies at utwente.nl
Mon Nov 3 06:29:04 EST 2008


Dear GHCers,

I ran face first into an assumption I had made on MVar operations (in 
Control.Concurrent); I had assumed there to be an atomic read (i.e. 
non-destructive read, as opposed to destructive consume/take). The following 
program illustrates what I had in mind.

testAtomic :: IO ()
testAtomic = do
	var <- newMVar 0
	putStrLn("Fork")
	forkIO (putMVar var 1 >> putStrLn "X")
	yield
	r1 <- readMVar var
	putStrLn("1")
	r2 <- takeMVar var
	putStrLn("2")
	r3 <- takeMVar var
	putStrLn("Result: " ++ show [r1,r2,r3])

If readMVar had been atomic, the result would be program termination with a 
result of [0,0,1] being output. However, readMVar simply combines takeMVar 
and putMVar, so the reading of r1 blocks after the takeMVar, because upon 
taking the MVar, the blocked thread wakes up, puts 1 in var and prints X. 
readMVar does not terminate for r1 (i.e. "1" is never printed).

I have now implemented my variable as a pair of MVars, one of which serves as 
a lock on the other. Both for performance reasons and for deadlock analysis, 
I would really like an atomic read on MVars, though. Does it exist? If not, 
why not?

Regards,
Philip


More information about the Glasgow-haskell-users mailing list