threadDelay problem

Adrian Hey ahey at
Tue Jan 6 09:17:54 EST 2004


Whilst experimenting with concurrency and a library which expects me to
use the usual event loop I wrote some test code like this..  

main :: IO ()
main = do
  forkIO forked

-- Main Loop
loop :: IO ()
loop = do
  maybeEvent <- pollEvent    -- non-blocking
  case maybeEvent of
    Just event -> do dispatch event
    Nothing    -> do threadDelay 10000 -- 10000 uS = 10 mS

-- Concurrent thread for test purposes
forked :: IO ()
forked = do threadDelay 1000000 -- 1000000 uS (= 1 S)
            putStrLn "Hello"

The idea is to stop a Haskell prog with no runable threads or events
to process hogging CPU time. I was a bit dissapointed to find that despite
this on my (otherwise idle) machine the above code was still using 96% of
cpu time.

But fiddling about a bit I found that by changing the thread delay in the
main loop to 20 mS the CPU usage dropped to 1% or so, which is much more
acceptable (well it did say 1/50 th second accuracy in the docs :-).

So this all seems OK, but I wonder if this is a reliable solution on all
platforms ghc is ported to (given the the consequence of getting this wrong
can be a very greedy program). Is the 20 mS resolution figure a function of
ghc only? Or might it depend on other factors too (like OS). Or might it
change with ghc version?

I think it would nice to have some reliable way to ensure that in reality
the thread delay will be as small as possible, but always greater than zero.
Maybe a threadDelayResolution constant could be provided?

Also, assuming that currently the (hypothetical) threadDelayResolution is
20000 and that in reality the actual threadDelay is N*20000 where N is an
integer, I think the docs for threadDelay should specify how N is calculated
from the argument of threadDelay. At the moment chosing a thread delay of
19999 sends my CPU usage right back up to 96%, though whether that's as
specified or merely a property of ghc 6.2 under Redhat 9 seems a little
ambiguous :-)

BTW, the docs for Control.Concurrent mention something about an -i<n> RTS
option, but I can't find any info on this in the user guide. When I try
it I get an error, listing all RTS options. There's no -i listed but there
is something that looks related, a -C option, but this doesn't appear in
the ghc user guide either :-(

Adrian Hey

More information about the Glasgow-haskell-users mailing list