Hi, On 09.10.2011, at 17:27, Daniel Fischer wrote:
> Jean-Marie Gaillourdet: >> the Eq instance of TypeRep shows the same non-deterministic behavior: > > Of course, equality on TypeReps is implemented by comparison of the Keys. > > On Sunday 09 October 2011, 16:40:13, Jean-Marie Gaillourdet wrote: >> Hi Daniel, > >> I've been chasing the source of the non-deterministic of my library for >> quite some time now. And at several points in time I had the impression >> that modifyMVar would not always be atomic. > > It isn't: > > "MVars offer more flexibility than IORefs, but less flexibility than STM. > They are appropriate for building synchronization primitives and performing > simple interthread communication; however they are very simple and > susceptible to race conditions, deadlocks or uncaught exceptions. Do not > use them if you need perform larger atomic operations such as reading from > multiple variables: use STM instead. > > In particular, the bigger functions in this module (readMVar, swapMVar, > withMVar, modifyMVar_ and modifyMVar) are simply the composition of a > takeMVar followed by a putMVar with exception safety. These only have > atomicity guarantees if all other threads perform a takeMVar before a > putMVar as well; otherwise, they may block." > > But I don't think that's the problem here. > >> (Of course under the >> assumption that no other code touches the MVar). This sentence referred to what you explained above. Although, my reference was quite cryptic. >> But in that case as >> well as in the case here it is only reproducible by looping the >> execution of the binary. Moving the loop into the Haskell program will >> show the bug in the first iteration or never. > > That's what I expect. > I think what happens is: > > -- from Data.Typeable > > cache = unsafePerformIO $ ... > > > mkTyConKey :: String -> Key > mkTyConKey str > = unsafePerformIO $ do > let Cache {next_key = kloc, tc_tbl = tbl} = cache > mb_k <- HT.lookup tbl str > case mb_k of > Just k -> return k > Nothing -> do { k <- newKey kloc ; > HT.insert tbl str k ; > return k } > > occasionally, the second thread gets to perform the lookup before the first > has updated the cache, so both threads create a new entry and update the > cache. > > If you loop in the Haskell programme, after the first round each thread > definitely finds an entry for "()", so the cache isn't updated anymore. That sounds plausible. Do you see any workaround? Perhaps repeatedly evaluating typeOf? Jean _______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users