[Haskell-cafe] scheduling an alarm

Brian Denheyer briand at aracnet.com
Wed Jan 27 10:31:42 EST 2010

On Tue, 26 Jan 2010 22:41:44 -0800
Thomas DuBuisson <thomas.dubuisson at gmail.com> wrote:

> Brian Denheyer <briand at aracnet.com> wrote:
> > On Tue, 26 Jan 2010 10:54:03 -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...
> >
> Infinite loop?  yes, that is what you wanted.  Memory gobbling?  Why
> would you think that? Are you assuming no TCO and a full stack push
> on every function call?  Haskell compilers don't work that way.

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

_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.

> 1) There are a million ways to do this - why does one working make you
> suspicious of another?  You can always test the other - it does work
> so long as you fix the missing 'do'.

The "suspicious" part, that was a joke.
Having something that works is nice, making sure I understand it is
better. I haven't used the Concurrent stuff before, so I'm just
being tentative.

> 2) It strikes me as funny you suspect the first way when there is zero
> fundamental difference between that and the way you posted except
> that: a) My version maintains the correct delay.
> b) My version forks the doEvent call and runs the action in the older
> thread while yours forks the action thread and keeps the doEvent in
> the older thread.  I suppose keeping the doEvent as the old thread is
> good so you can kill it with the original ThreadID that would be
> returned to the caller.

Thanks for the explanation, as I said I'm a little fuzzy on what
constitutes a thread, so the two versions will help.

One interesting thing I noticed in the docs (which is not important
for what I am trying to do, just interesting):

There is no guarantee that the thread will be rescheduled promptly when
the delay has expired, but the thread will never continue to run
earlier than specified. 

I expect that this means "promptly" in the sense of not accurately,
however I wonder what the upper bound on the (potential) delay is ?

> Some people miss the fact that threadDelay is a us value and an Int
> type - this limits the maximum delay to something like 35 minutes
> (assume a 32 bit Int) or even just 134 seconds if you go by Haskell
> 98 minimum of 27 bit Ints.  Just making sure you realize this seeing
> as we are talking about delays in that order of magnitude.  I advise
> the overly-complex but functional Control-Event package if you want
> longer delays.

I did notice that the delay is in us.  35 minutes is plenty of time.  I
can always delay twice ;-)

Thanks for pointing me to control event, that looks useful !


More information about the Haskell-Cafe mailing list