[GHC] #10639: Optimization changes concurrent program's behaviour

#10639: Optimization changes concurrent program's behaviour -------------------------------------+------------------------------------- Reporter: gizmo.mk0 | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Keywords: | Operating System: Windows Architecture: x86_64 | Type of failure: Incorrect result (amd64) | at runtime Test Case: | Blocked By: Blocking: | Related Tickets: Differential Revisions: | -------------------------------------+------------------------------------- Here is a program that spawns a thread from the main thread, which tries to constantly write out a message to the console. {{{#!hs module Main where import Control.Concurrent (forkIO) main :: IO () main = do _ <- forkIO $ runForever $ putStrLn "Hey" runForever $ return () runForever :: IO () -> IO () runForever action = action >> runForever action }}} If you compile it with 'ghc main', it works correctly - it prints out the message continuously, and you can terminate it by pressing Ctrl-C. However, if you compile it with 'ghc -O main' (or -O2, or -O3...), it doesn't print out anything, and the only way to exit is to kill the process from Task Manager. This was reproducable with GHC 7.10.1, on a Windows 7 x64 machine, with an AMD A4-5300 APU. ''(Disclaimer: this is my first bugreport, and I'm not sure what else can I do to investigate this issue.)'' -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10639 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10639: Optimization changes concurrent program's behaviour -------------------------------------+------------------------------------- Reporter: gizmo.mk0 | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: Windows | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Description changed by gizmo.mk0: Old description:
Here is a program that spawns a thread from the main thread, which tries to constantly write out a message to the console.
{{{#!hs module Main where
import Control.Concurrent (forkIO)
main :: IO () main = do _ <- forkIO $ runForever $ putStrLn "Hey" runForever $ return ()
runForever :: IO () -> IO () runForever action = action >> runForever action }}}
If you compile it with 'ghc main', it works correctly - it prints out the message continuously, and you can terminate it by pressing Ctrl-C. However, if you compile it with 'ghc -O main' (or -O2, or -O3...), it doesn't print out anything, and the only way to exit is to kill the process from Task Manager.
This was reproducable with GHC 7.10.1, on a Windows 7 x64 machine, with an AMD A4-5300 APU.
''(Disclaimer: this is my first bugreport, and I'm not sure what else can I do to investigate this issue.)''
New description: Here is a program that spawns a thread from the main thread, which tries to constantly write out a message to the console. {{{#!hs module Main where import Control.Concurrent (forkIO) main :: IO () main = do _ <- forkIO $ runForever $ putStrLn "Hey" runForever $ return () runForever :: IO () -> IO () runForever action = action >> runForever action }}} If you compile it with 'ghc main', it works correctly - it prints out the message continuously, and you can terminate it by pressing Ctrl-C. However, if you compile it with 'ghc -O main' (or -O2, or -O3...), it doesn't print out anything, and the only way to exit is to kill the process from Task Manager. This was reproducable with GHC 7.10.1, on a Windows 7 x64 machine, with an AMD A4-5300 APU. ''EDIT: As it turns out, using "yield" instead of "return ()" solves the problem. It seems I misunderstood how forkIO works. However, I'm not sure if the current working is intentional or not, so I think I should leave this ticket open - just to be on the safe side.'' -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10639#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10639: Optimization changes concurrent program's behaviour -------------------------------------+------------------------------------- Reporter: gizmo.mk0 | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: Windows | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Changes (by slyfox): * cc: slyfox (added) Comment: It's a result of cooperative multitasking in ghc: Trac #367 In short: non-allocating threads can starve other threads, can be worked- around by -fno-omit-yields -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10639#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10639: Tight (non-allocating) loop freezes the scheduler -------------------------------------+------------------------------------- Reporter: gizmo.mk0 | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: Windows | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Changes (by simonpj): * cc: slyfox (removed) Comment: My guess is this. With optimisation the `runForever (return ())` turns into a tight loop that does not allocate. Once that loop gets control of the CPU, it never gives it up. Without optimisation, the loop does allocation. This is really a long-standing bug, just a rather rare one. Usually we check whether a thread's time quantum has expired when checking for heap- allocation overflow. If there is no allocation we don't check. I'm pretty sure this is it, so I'll change the title of the ticket. It should be documented though. Would someone feel able to add a bullet to the [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/bugs.html bugs section] of the user manual? Fixing it properly is tricky, because we don't want to add zillions of checks, and identifying all the risky points is hard. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10639#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10639: Tight (non-allocating) loop freezes the scheduler -------------------------------------+------------------------------------- Reporter: gizmo.mk0 | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: Windows | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by gizmo.mk0): "It should be documented though. Would someone feel able to add a bullet to the bugs section of the user manual?" Is it something that I, who has almost zero knowledge of the workings of the compiler, can do? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10639#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10639: Tight (non-allocating) loop freezes the scheduler -------------------------------------+------------------------------------- Reporter: gizmo.mk0 | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: Windows | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by bgamari): See Phab:D1127 for one possible wording. @gizmo.mk0, feel free to suggest improvements to the language. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10639#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10639: Tight (non-allocating) loop freezes the scheduler -------------------------------------+------------------------------------- Reporter: gizmo.mk0 | Owner: Type: bug | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: Windows | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Changes (by bgamari): * status: new => patch -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10639#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10639: Tight (non-allocating) loop freezes the scheduler -------------------------------------+------------------------------------- Reporter: gizmo.mk0 | Owner: Type: bug | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: Windows | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: Phab:D1127 -------------------------------------+------------------------------------- Changes (by bgamari): * differential: => Phab:D1127 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10639#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10639: Tight (non-allocating) loop freezes the scheduler
-------------------------------------+-------------------------------------
Reporter: gizmo.mk0 | Owner:
Type: bug | Status: patch
Priority: normal | Milestone:
Component: Compiler | Version: 7.10.1
Resolution: | Keywords:
Operating System: Windows | Architecture: x86_64
Type of failure: Incorrect result | (amd64)
at runtime | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Revisions: Phab:D1127
-------------------------------------+-------------------------------------
Comment (by Ben Gamari

#10639: Tight (non-allocating) loop freezes the scheduler -------------------------------------+------------------------------------- Reporter: gizmo.mk0 | Owner: Type: bug | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: Windows | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: Phab:D1127 -------------------------------------+------------------------------------- Comment (by Phyx-): Can we close this and #367 or is there something else needed other than documentation? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10639#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10639: Tight (non-allocating) loop freezes the scheduler
-------------------------------------+-------------------------------------
Reporter: gizmo.mk0 | Owner:
Type: bug | Status: patch
Priority: normal | Milestone:
Component: Compiler | Version: 7.10.1
Resolution: | Keywords:
Operating System: Windows | Architecture: x86_64
Type of failure: Incorrect result | (amd64)
at runtime | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s): Phab:D1127
-------------------------------------+-------------------------------------
Comment (by Ben Gamari

#10639: Tight (non-allocating) loop freezes the scheduler -------------------------------------+------------------------------------- Reporter: gizmo.mk0 | Owner: Type: bug | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Resolution: duplicate | Keywords: Operating System: Windows | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #367 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by thomie): * status: patch => closed * differential: Phab:D1127 => * resolution: => duplicate * related: => #367 Comment: The documentation has been improved. #367 is still open, with milestone bottom. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10639#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC