Simon Jakobi pushed to branch wip/sjakobi/nonmoving-gc-timeout at Glasgow Haskell Compiler / GHC

Commits:

4 changed files:

Changes:

  • rts/Schedule.c
    ... ... @@ -2051,7 +2051,26 @@ forkProcess(HsStablePtr *entry
    2051 2051
         waitForCapability(&cap, task);
    
    2052 2052
     
    
    2053 2053
     #if defined(THREADED_RTS)
    
    2054
    -    stopAllCapabilities(&cap, task);
    
    2054
    +    while (true) {
    
    2055
    +        stopAllCapabilities(&cap, task);
    
    2056
    +
    
    2057
    +        // The nonmoving collector's worker is not copied by fork(). Only
    
    2058
    +        // proceed when it is idle, keeping its lock held to prevent another
    
    2059
    +        // collection from starting before the fork. We must not wait for an
    
    2060
    +        // active mark while holding capabilities since the mark may need to
    
    2061
    +        // synchronize with the mutator before it can finish.
    
    2062
    +        if (nonmovingBlockConcurrentMark(false)) {
    
    2063
    +            break;
    
    2064
    +        }
    
    2065
    +
    
    2066
    +        releaseAllCapabilities(n_capabilities, NULL, task);
    
    2067
    +        CHECK(nonmovingBlockConcurrentMark(true));
    
    2068
    +        nonmovingUnblockConcurrentMark();
    
    2069
    +        cap = NULL;
    
    2070
    +        waitForCapability(&cap, task);
    
    2071
    +    }
    
    2072
    +#else
    
    2073
    +    CHECK(nonmovingBlockConcurrentMark(false));
    
    2055 2074
     #endif
    
    2056 2075
     
    
    2057 2076
         // no funny business: hold locks while we fork, otherwise if some
    
    ... ... @@ -2089,6 +2108,8 @@ forkProcess(HsStablePtr *entry
    2089 2108
     
    
    2090 2109
         if (pid) { // parent
    
    2091 2110
     
    
    2111
    +        nonmovingUnblockConcurrentMark();
    
    2112
    +
    
    2092 2113
             RELEASE_LOCK(&sched_mutex);
    
    2093 2114
             RELEASE_LOCK(&sm_mutex);
    
    2094 2115
             RELEASE_LOCK(&stable_ptr_mutex);
    
    ... ... @@ -2213,6 +2234,10 @@ forkProcess(HsStablePtr *entry
    2213 2234
                 generations[g].threads = END_TSO_QUEUE;
    
    2214 2235
             }
    
    2215 2236
     
    
    2237
    +        // The persistent nonmoving collector worker is an OS thread and was
    
    2238
    +        // not copied by fork(). Recreate it before running the child action.
    
    2239
    +        nonmovingInitAfterFork();
    
    2240
    +
    
    2216 2241
             // The timer thread is not present in the child process, so we need
    
    2217 2242
             // to initialise the timer again.
    
    2218 2243
             initTimer();
    

  • rts/sm/NonMoving.c
    ... ... @@ -754,6 +754,12 @@ void nonmovingInit(void)
    754 754
         nonmovingMarkInit();
    
    755 755
     }
    
    756 756
     
    
    757
    +void nonmovingInitAfterFork(void)
    
    758
    +{
    
    759
    +    if (! RtsFlags.GcFlags.useNonmoving) return;
    
    760
    +    nonmovingInitConcurrentWorker();
    
    761
    +}
    
    762
    +
    
    757 763
     void nonmovingExit(void)
    
    758 764
     {
    
    759 765
         if (! RtsFlags.GcFlags.useNonmoving) return;
    

  • rts/sm/NonMoving.h
    ... ... @@ -150,6 +150,7 @@ extern struct NonmovingHeap nonmovingHeap;
    150 150
     extern memcount nonmoving_segment_live_words;
    
    151 151
     
    
    152 152
     void nonmovingInit(void);
    
    153
    +void nonmovingInitAfterFork(void);
    
    153 154
     void nonmovingExit(void);
    
    154 155
     bool nonmovingConcurrentMarkIsRunning(void);
    
    155 156
     
    

  • testsuite/tests/rts/T12903.hs
    1 1
     import Control.Concurrent
    
    2 2
     import Control.Exception
    
    3
    +import System.Exit
    
    3 4
     import System.IO
    
    4 5
     import System.Posix
    
    5 6
     import System.Posix.IO
    
    ... ... @@ -19,3 +20,5 @@ main = do
    19 20
       "registered" <- hGetLine hdl
    
    20 21
       signalProcess sigINT pid
    
    21 22
       putStrLn =<< hGetLine hdl
    
    23
    +  Just (Exited ExitSuccess) <- getProcessStatus True False pid
    
    24
    +  return ()