[I am reading ghc-bugs via the list archives, Cc'ing me would make me see responses faster]

Here's a simple memoization function:

applyMemo :: (Eq a1,Show a1) => (a1 -> b) -> MVar [(a1,b)] -> (a1 -> b)
applyMemo f refTable x1 = unsafePerformIO $ do
    -- print x1
    table <- takeMVar refTable
    let key = x1
    case lookup key table of
      Nothing -> do
        let result = f x1
        putMVar refTable $! (key,result):table
        return result
      Just memo -> putMVar refTable table >> return memo


The code above is a cut-down example. Initially, I tried to use Data.HashTable, then IORef (Data.Map ...), then MVars. However, what remains is that I get funny results: <<loop>>, "thread blocked indefinitely", hangs, depending on the exact implementation of applyMemo, whether I use ghci or ghc, and which function I memoize (something with a more interesting call pattern than fib).

This is with ghc-6.6 from haskell.org on MacOSX/Intel, same hangs on amd64-linux.

I have some speculation what's going wrong, namely that one version of the unsafePerformIO code is interrupted by another (triggered by some lazy computation), the latter then blocks on the MVar, and the RTS cannot proceed.

Oh, and uncommenting the "print" statement makes the error go away, presumably because x1 is fully evaluated?

Anyway, this code is more or less lifted from the "Stretching the Storage Manager" paper [1], and since then there have been quite some invasive changes to the RTS, if I am not mistaken.

What am I doing wrong, and how can I do it right? :)

(If pressed I could provide actual code which triggers the bug, but it will take me a while to extract it, and also I would rather have it not public for now.)


Cheers,
Michael

[1] http://research.microsoft.com/Users/simonpj/Papers/weak.ps.gz


_______________________________________________
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to