<div dir="ltr">Hi Iavor,<div><br></div><div>You might be interested in what Edward has written about this:</div><div><br></div><div><a href="http://blog.ezyang.com/2014/01/so-you-want-to-add-a-new-concurrency-primitive-to-ghc/">http://blog.ezyang.com/2014/01/so-you-want-to-add-a-new-concurrency-primitive-to-ghc/</a></div><div><br></div><div>I would say when we do have a memory model for GHC the program you gave will almost certainly be correct.  MVar operations should be full synchronization operations.  There are some bugs on relaxed systems with initialization that I think are being addressed.  I can't find the tickets at the moment.</div><div><br></div><div>Ryan</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Oct 21, 2016 at 1:19 PM, Iavor Diatchki <span dir="ltr"><<a href="mailto:iavor.diatchki@gmail.com" target="_blank">iavor.diatchki@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hello,<div><br></div><div>recently, I and a few colleagues have been wondering about the interaction between IORefs and MVars, and we can't seem to find any explicit documentation stating the behavior, so I was wondering if anyone might know the answer.</div><div><br></div><div>The question is:  is it safe to use IORefs in a multi-threaded program, provided that the uses are within a "critical section" implemented with MVars.  Here is a simple program to illustrate the situation: we have two threads, each thread takes a lock, increments a counter, then releases the lock:</div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">> import Control.Concurrent<br></font></div><div><div><font face="monospace, monospace">> import Data.IORef</font></div><div><font face="monospace, monospace">> </font></div><div><font face="monospace, monospace">> main :: IO ()</font></div><div><font face="monospace, monospace">> main =</font></div><div><font face="monospace, monospace">>   do lock    <- newMVar ()</font></div><div><font face="monospace, monospace">>      counter <- newIORef 0</font></div><div><font face="monospace, monospace">>      forkIO (thread lock counter)</font></div><div><font face="monospace, monospace">>      thread lock counter</font></div><div><font face="monospace, monospace">></font></div><div><font face="monospace, monospace">> thread :: MVar () -> IORef Integer -> IO a</font></div><div><font face="monospace, monospace">> thread lock counter =</font></div><div><font face="monospace, monospace">>   do takeMVar lock</font></div><div><font face="monospace, monospace">>      value <- readIORef counter</font></div><div><font face="monospace, monospace">>      print value</font></div><div><font face="monospace, monospace">>      writeIORef counter (value + 1)</font></div><div><font face="monospace, monospace">>      putMVar lock ()</font></div><div><font face="monospace, monospace">>      thread lock counter</font></div></div><div><br></div><div>The question is if this program has a race condition or not, due to the use of IORefs?  More explicitly, the concern is if a write to an IORef in one thread is guaranteed to be seen by a read from the same IORef in another thread, provided that there is proper synchronization between the two.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>-Iavor</div><div><br></div><div><br></div><div><br></div><div><br></div></font></span></div>
<br>______________________________<wbr>_________________<br>
ghc-devs mailing list<br>
<a href="mailto:ghc-devs@haskell.org">ghc-devs@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/ghc-devs</a><br>
<br></blockquote></div><br></div>