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 |