atomicWriteIORef was implemented using atomicModifyIORef,
which has to allocate memory. But atomicWriteIORef doesn't need
nearly that much power; a simple CAS loop can do the trick.
Note: The primop alternative is explored in D4887.
|No Unit Test Coverage|
|Build 48731: [GHC] Linux/amd64: Continuous Integration|
|Build 48730: [GHC] OSX/amd64: Continuous Integration|
|Build 48729: [GHC] Windows/amd64: Continuous Integration|
|Build 48728: arc lint + arc unit|
A test would be nice.
let's export casIORef too? It's sometimes useful if you don't want to pull in atomic-primops
Is this really the only way to implement atomicModifyIORef? It seems like overkill to have a CAS loop just to get a barrier. Why would we need to loop?
I'd really like to understand what the danger is here, the comment is a bit vague. Is there a real problem? If so, what's the assumption we're making that would be invalid, how would it be invalidated, and how does lazy fix it? How will we know if it goes wrong?
Good point. We surely need a loop to implement the replacement/swap operation, but shouldn't need it for just writing. But I don't know off the top of my head how to just ask for a barrier.
A test does sound like a good idea.
Would that be sufficient to implement atomicReplaceIORef (which will be renamed atomicSwapIORef based on a suggestion by "winter")? I'm way outside my comfort zone here; could you advise on implementation details, or perhaps commandeer this differential to do it right?
I thought we could maybe have trouble if the result was demanded strictly, but now I realize we won't: we're saved by the fact that old is only returned conditionally.
Yes, that should be exactly atomicReplaceIORef. Doing it right is a lot of work :D. For one take on this see: https://dl.acm.org/citation.cfm?id=3018746. Also some relevant earlier discussion here: http://blog.ezyang.com/2014/01/so-you-want-to-add-a-new-concurrency-primitive-to-ghc/