[Haskell-cafe] scheduling an alarm

Neil Brown nccb2 at kent.ac.uk
Thu Jan 28 10:21:27 EST 2010

Brian Denheyer wrote:
> On Tue, 26 Jan 2010 22:41:44 -0800
> Thomas DuBuisson <thomas.dubuisson at gmail.com> wrote:
>>>>> doEvent f usDelay = forkIO $
>>>>>   threadDelay usDelay
>>>>>   doEvent f usDelay
>>>>>   f
>>> Are you sure that's right ? It seems to be a memory-gobbling
>>> infinite loop...
> Why would I think that ?
> I think that because the following code:
> import Control.Concurrent
> f = putStrLn "foo"
> doEvent f usDelay = do forkIO $ threadDelay usDelay
>                        doEvent f usDelay
>                        f
> _really_ _does_ start to consume all of the memory on my system, that's
> why.  I don't know why, but that's what it does on my system.  It's not
> obvious to me that it should do that.  So maybe ghci is not doing TCO.
The code you have presented at the bottom is an infinite loop that I 
would expect to consume all the memory on your system.  That code spins 
at 100% busy, forking off threadDelay calls without ever stopping, and 
will never perform "f".  Ouch -- infinite loop, and likely hugely 
memory-consuming (in fact, I'm not sure how the last poster didn't find 
that it consumed a lot of memory...).  However, that code is slightly 
different to the original (that I have left in up the top) which had a 
crucial "do" missing (although you can infer it from the indentation).  
The original code should be:

doEvent f usDelay = forkIO $ do threadDelay usDelay
                                doEvent f usDelay

That is, the latter two lines should be inside the forkIO block, not 
after it.  This code will wait for the given delay, then fork a new 
thread, then perform f.  As long as f takes less time to complete than 
usDelay, this code should not eat memory and is quite reasonable.

I hope that clears up the confusion.


More information about the Haskell-Cafe mailing list