Race condition in setNumCapabilities
In HEAD, the following program sometimes deadlocks (about 1/10 of the time).
import Control.Concurrent
import Control.Monad
import GHC.Conc
main = do
mainTid <- myThreadId
labelThread mainTid "main"
forM_ [0..0] $ \i -> forkIO $ do
subTid <- myThreadId
labelThread subTid $ "sub " ++ show i
forM_ [0..100000000] $ \j -> putStrLn $ "sub " ++ show i ++ ": " ++ show j
yield
setNumCapabilities 2
The problem seems to be that there is a race condition between setNumCapabilites and a Task returning from a foreign call. Specifically, a sequence of events like the following can happen:
- Task 0 makes a foreign call.
- Task 1 calls setNumCapabilities()
- The call on task 0 returns; it reads task->cap from the memory.
- Task 1 moves the Capabilities, invalidating all pointers to them.
- Task 0 takes over the invalidated Capability.
The attached patch adds an ASSERT to the RTS to demonstrate the problem (it does not fix the problem).
Trac metadata
Trac field | Value |
---|---|
Version | 7.7 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Runtime System |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |