
Hello, Recently, I stumbled over E.Z.Yang's "Safety first: FFI and threading"[1] post and then while experimenting with unsafe-imported FFI functions I've noticed a somewhat surprising behaviour: Consider the following contrived program: --8<---------------cut here---------------start------------->8--- import Foreign.C import Control.Concurrent import Control.Monad import Data.Time.Clock.POSIX (getPOSIXTime) foreign import ccall unsafe "unistd.h sleep" c_sleep_unsafe :: CUInt -> IO CUInt main :: IO () main = do putStrLnTime "main started" _ <- forkIO (sleepLoop 10 >> putStrLnTime "sleepLoop finished") yield putStrLnTime "after forkIO" threadDelay (11*1000*1000) -- 11 seconds putStrLnTime "end of main" where putStrLnTime s = do t <- getPOSIXTime putStrLn $ init (show t) ++ "\t" ++ s sleepLoop n = do n' <- c_sleep_unsafe n unless (n' == 0) $ do putStrLnTime "c_sleep_unsafe got interrupted" sleepLoop n' --8<---------------cut here---------------end--------------->8--- When compiled with GHC-7.6.3/linux/amd64 with "-O2 -threaded" and executed with "+RTS -N4", the following output is emitted: 1367838802.137419 main started 1367838812.137727 after forkIO 1367838812.137783 sleepLoop finished 1367838823.148733 end of main which shows that the forkIO of the unsafe ccall effectively blocks the main thread; Moreover, when looking at the process table, I saw that 3 threads were occupying 100% CPU time each for 10 seconds until the 'after forkIO' was emitted. So what is happening here exactly, why do the 3 remaining HECs busy-wait during that FFI call instead of continuing the execution of the main thread? Do *all* foreign unsafe ccalls (even short ones) cause N-1 HECs to spend time in some kind of busy looping? [1]: http://blog.ezyang.com/2010/07/safety-first-ffi-and-threading/ Cheers, hvr