
At Wed, 18 May 2011 09:56:22 +0100, Simon Marlow wrote:
Ok. I'm not sure how feasible RCU is with IORefs, or even whether it's necessary. After all, the usual pattern of having readers use readIORef while writers use atomicModifyIORef gives the RCU cost model (zero overhead for readers, expensive writes) with far less complexity. Garbage collection does the job of reclamation automatically. Have I missed something here?
Right, that's what I was calling RCU. Usually the hard part in RCU is the garbage collection. Obviously if you needed to do something else like close a file handle, then IORefs are not sufficient. But for a lot of applications of RCU, IORefs plus garbage collection should be sufficient.
A slight improvement over this scheme is to use TVar with readTVarIO for the readers (no transaction involved), and transactions for the writers. This greatly increases the scope of what a writer can do, since they can perform an update on a bunch of state at the same time.
Good point.
There is an operational semantics in the Concurrent Haskell paper that does not admit the behaviour you describe, but I'll add something to the docs to that effect.
Ah, you got me. I probably should have looked at that paper, which is linked to from Control.Concurrent. Still, in some cases (not necessarily here), papers are static and code continues to evolve, so it's nice to stuff documented in haddock as well.
That's a good point - readMVar cannot be optimised to avoid the lock. In fact, readMVar is just
readMVar m = do x <- takeMVar m; putMVar m x; return x
although there have been suggestions that we should make it atomic. If we were to do so, it would still have to use a barrier to avoid reordering.
What would be even cooler would be if swapMVar could be made atomic. Or better yet, if there could be a compareAndSwapMVar, since on some architectures (though not x86) that could be a single instruction and allow for truly wait-free data types. (That might not be possible without sacrificing referential transparency, since the obvious implementation would involve comparing pointers rather than values.) David