Stretching the Storage Manager a little too much...

Michael Weber michaelw at foldr.org
Mon Jan 29 13:12:33 EST 2007


[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





More information about the Glasgow-haskell-bugs mailing list