I have the following piece of code:

module Main where import Data.IORef import qualified Data.ByteString as S import Control.Monad import Control.Concurrent main :: IO () main = do var <- newIORef False forkIO $ forever $ do status <- readIORef var if status then putStrLn "main: file was read" else putStrLn "main: file not yet read" threadDelay 10000 threadDelay 200000 putStrLn ">>! going to read file" --threadDelay 200000 -- str <- S.readFile "large2" putStrLn ">>! finished reading file" writeIORef var True threadDelay 200000

I compile the code and run it like this:

$ ghc -threaded --make test.hs $ dd if=/dev/urandom of=large bs=800000 count=1024 $ ./test +RTS -N3 <...> main: file not yet read main: file not yet read main: file not yet read main: file not yet read >>! going to read file >>! finished reading file main: file was read main: file was read main: file was read main: file was read <...>

That is, the program pauses when reading a file. I find this confusing because if I replace readFile with threadDelay it yield control correctly.

What is going on in here? Isn't GHC mapping forkIO 'd code to a different system thread?

(I am using Mac OS X 10.8.5, but people has reported the same behavior on Ubuntu and Debian)