semantics of concurrent program depends on -O level, -f[no-]omit-yields
I am surprised by the behaviour of the program below (the interesting property is whether it will output "foo").
Behaviours (plural) actually: it seems to depend on optimisation level, on omit-yields, and on very small changes in the source code:
It does print (mostly), when compiled with -O0. It does not, when compiled with -O2. With -O2 -fno-omit-yields, it will print. With -O0 -fno-omit-yields, and when I remove the two newTVar in the beginning, it will mostly not print.
How come?
These differences already occur with the last two lines replaced by "forever $ return ()", so the STM stuff may be inessential here. But that's the context where I came across the problem.
See also discussion at https://mail.haskell.org/pipermail/haskell-cafe/2018-November/130274.html
import Control.Concurrent.STM
import Control.Concurrent ( forkIO )
import Control.Monad ( forever )
import System.IO
main = do
atomically $ newTVar "bar"
atomically $ newTVar False
forkIO $ putStrLn "foo"
x <- atomically $ newTVar False
forever $ atomically $ writeTVar x True
Trac metadata
| Trac field | Value |
|---|---|
| Version | 8.6.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture |