[GHC] #9285: IO manager startup procedure somewhat odd

#9285: IO manager startup procedure somewhat odd ------------------------------------+------------------------------------- Reporter: edsko | Owner: Type: bug | Status: new Priority: low | Milestone: Component: Compiler | Version: 7.8.2 Keywords: | Operating System: Unknown/Multiple Architecture: Unknown/Multiple | Type of failure: None/Unknown Difficulty: Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | ------------------------------------+------------------------------------- Currently the RTS startup procedure for the threaded runtime with a single capability looks something like this: '''1. Capability gets initialized''' {{{ hs_main real_main hs_init_ghc initScheduler initCapabilities }}} '''2. IO Manager is started''' {{{ hs_main real_main hs_init_ghc ioManagerStart }}} '''3. ensureIOManagerIsRunning''' The IO manager of course is mostly written in Haskell, so `ioManagerStart` does {{{ cap = rts_lock(); rts_evalIO(&cap,&base_GHCziConcziIO_ensureIOManagerIsRunning_closure,NULL); rts_unlock(cap); }}} '''4. Bound task is created and we start running Haskell code''' Since this is the first call to `rts_lock`, it creates a bound task to correspond to the current OS thread. '''5. Haskell code does a safe FFI call: create worker task 1''' The first safe FFI call that the IO manager makes (ignoring `labelThread`) is to `c_setIOManagerControlFd`. At this point, the bound task gets suspended and we create a worker task. '''6. Worker task 1 starts executing `GHC.Event.Manager.loop`''' The worker tasks gets suspended due to an explicit call to `yield` in `GHC.Event.Manager.step`, at which point the bound task continues execution. It continues and finishes (`ensureIOManagerRunning` completes). The worker task takes over. '''7. Worker task 1 does a safe FFI call to `I.poll`, create new worker task 2''' (This safe call is from `GHC.Event.Manager.step`) '''8. Worker task 2 executes `GHC.Event.TimerManager.loop`, and does safe FFI call to `I.poll`; create worker task 3''' This worker task will remain spare for now. '''9. Start executing the actual main function''' The IO manager calls `rts_unlock`, which verifies if there are any spare workers available; it finds that there are and doesn't start a new one. Then when we start `main` itself of course we go through this `rts_lock, rts_evalIO, rts_unlock` sequence ''again''. This is somewhat confusing, and makes tracing the startup of the code more difficult to interpret. It seems that this could be simpler: only a single `rts_lock` should be necessary, in which we first call `ensureIOManagerIsRunning` and then `main`, followed by a single `rts_unlock`. A similar simplification should be possible in `forkProcess`. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9285 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9285: IO manager startup procedure somewhat odd -------------------------------------+------------------------------------ Reporter: edsko | Owner: Type: bug | Status: new Priority: low | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by duncan): Actually it looks like `forkProcess` is already simpler. It only calls `ioManagerStartCap(&cap);` because it's already in the context of holding the capability. So in summary, we're suggesting that in the rts startup we should be using `ioManagerStartCap(&cap);` in a context where we already hold the initial cap and before we run main. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9285#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9285: IO manager startup procedure somewhat odd -------------------------------------+------------------------------------ Reporter: edsko | Owner: Type: bug | Status: new Priority: low | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by duncan): So I suppose I'm suggesting something like this: {{{ diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c index 8e7e11d..38435d8 100644 --- a/rts/RtsStartup.c +++ b/rts/RtsStartup.c @@ -258,11 +258,6 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config) // ToDo: make this work in the presence of multiple hs_add_root()s. initProfiling2(); - // ditto. -#if defined(THREADED_RTS) - ioManagerStart(); -#endif - /* Record initialization times */ stat_endInit(); }}} {{{ diff --git a/rts/RtsMain.c b/rts/RtsMain.c index df63716..68b2c79 100644 --- a/rts/RtsMain.c +++ b/rts/RtsMain.c @@ -60,6 +60,9 @@ static void real_main(void) /* ToDo: want to start with a larger stack size */ { Capability *cap = rts_lock(); +#if defined(THREADED_RTS) + ioManagerStartCap(&cap); +#endif rts_evalLazyIO(&cap,progmain_closure, NULL); status = rts_getSchedStatus(cap); rts_unlock(cap); }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9285#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9285: IO manager startup procedure somewhat odd -------------------------------------+------------------------------------ Reporter: edsko | Owner: Type: bug | Status: new Priority: low | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Changes (by AndreasVoellmy): * cc: AndreasVoellmy (added) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9285#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9285: IO manager startup procedure somewhat odd -------------------------------------+------------------------------------- Reporter: edsko | Owner: simonmar Type: bug | Status: new Priority: low | Milestone: Component: Runtime | Version: 7.8.2 System | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Changes (by thomie): * cc: simonmar (added) * owner: => simonmar * component: Compiler => Runtime System -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9285#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9285: IO manager startup procedure somewhat odd -------------------------------------+------------------------------------- Reporter: edsko | Owner: simonmar Type: task | Status: patch Priority: low | Milestone: Component: Runtime System | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Changes (by thomie): * status: new => patch * type: bug => task -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9285#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9285: IO manager startup procedure somewhat odd -------------------------------------+------------------------------------- Reporter: edsko | Owner: simonmar Type: task | Status: patch Priority: low | Milestone: 8.4.1 Component: Runtime System | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by dfeuer): * milestone: => 8.4.1 Comment: Setting a milestone. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9285#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9285: IO manager startup procedure somewhat odd -------------------------------------+------------------------------------- Reporter: edsko | Owner: simonmar Type: task | Status: closed Priority: low | Milestone: 8.6.1 Component: Runtime System | Version: 7.8.2 Resolution: wontfix | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * status: patch => closed * resolution: => wontfix * milestone: 8.4.1 => 8.6.1 Comment: I'm not sure that the proposal in comment:2 is reasonable; this would mean that calling `hs_init_ghc` would be insufficient to fully initialize the runtime environment. This in turn means that users who drive the RTS directly would need to duplicate the IO manager initialization logic. All of this for questionable benefit. I'm going to close this as WONTFIX but do say if there is a different refactoring that you would like to see. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9285#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC