Duncan Coutts pushed to branch wip/dcoutts/idle-gc-rewrite2 at Glasgow Haskell Compiler / GHC

Commits:

4 changed files:

Changes:

  • rts/IdleGC.c
    ... ... @@ -48,7 +48,9 @@
    48 48
     
    
    49 49
      The idle GC is also the only occasion when deadlock detection is performed.
    
    50 50
      So note that disabling idle GC with RTS flag `-I0` will also disable deadlock
    
    51
    - detection. See Note [Deadlock detection] for further details.
    
    51
    + detection.
    
    52
    +
    
    53
    +TODO: refer to the deadlock detection note for further details, once that note exists.
    
    52 54
     */
    
    53 55
     
    
    54 56
     /*
    
    ... ... @@ -209,22 +211,30 @@ static void unpauseTimerUnlessProfiling(void);
    209 211
     
    
    210 212
     void initIdleGc(void)
    
    211 213
     {
    
    212
    -    /* Use division rounding up (a+b-1)/b, to avoid getting 0 ticks, as this
    
    213
    -     * would give unexpected results.
    
    214
    -     */
    
    215
    -    idlegc_delay_ticks =
    
    216
    -        (RtsFlags.GcFlags.idleGCDelayTime + RtsFlags.MiscFlags.tickInterval - 1)
    
    217
    -      / RtsFlags.MiscFlags.tickInterval;
    
    214
    +    if (RtsFlags.GcFlags.doIdleGC) {
    
    215
    +        /* Use division rounding up (a+b-1)/b, to avoid getting 0 ticks, as this
    
    216
    +         * would give unexpected results.
    
    217
    +         */
    
    218
    +        idlegc_delay_ticks =
    
    219
    +            (RtsFlags.GcFlags.idleGCDelayTime + RtsFlags.MiscFlags.tickInterval - 1)
    
    220
    +          / RtsFlags.MiscFlags.tickInterval;
    
    218 221
     
    
    219
    -    inter_idlegc_delay_ticks =
    
    220
    -        (RtsFlags.GcFlags.interIdleGCWait + RtsFlags.MiscFlags.tickInterval - 1)
    
    221
    -      / RtsFlags.MiscFlags.tickInterval;
    
    222
    +        inter_idlegc_delay_ticks =
    
    223
    +            (RtsFlags.GcFlags.interIdleGCWait + RtsFlags.MiscFlags.tickInterval - 1)
    
    224
    +          / RtsFlags.MiscFlags.tickInterval;
    
    222 225
     
    
    223
    -    /* The -Iw<n> parameter is supposed to control times *between* idle GCs,
    
    224
    -     * not time since program start. So by initialising to the negative of the
    
    225
    -     * interval then we can do an idle GC almost immediately if needed.
    
    226
    -     */
    
    227
    -    shared_last_idlegc_tick = -inter_idlegc_delay_ticks;
    
    226
    +        /* The -Iw<n> parameter is supposed to control times *between* idle GCs,
    
    227
    +         * not time since program start. So by initialising to the negative of the
    
    228
    +         * interval then we can do an idle GC almost immediately if needed.
    
    229
    +         */
    
    230
    +        shared_last_idlegc_tick = -inter_idlegc_delay_ticks;
    
    231
    +    } else {
    
    232
    +        /* When idle GC is disabled, we turn off the timer tick after one tick
    
    233
    +         * of all caps being idle.
    
    234
    +         */
    
    235
    +        idlegc_delay_ticks = 1;
    
    236
    +        inter_idlegc_delay_ticks = 0;
    
    237
    +    }
    
    228 238
     
    
    229 239
         debugTrace(DEBUG_idlegc,
    
    230 240
                    "Idle GC (tick %d): initialising, delay ticks = %d,"
    
    ... ... @@ -379,14 +389,14 @@ void handleIdleGcTick(void)
    379 389
          */
    
    380 390
         if (RtsFlags.GcFlags.doIdleGC) {
    
    381 391
             debugTrace(DEBUG_idlegc, "Idle GC (tick %d): transition to PENDING",
    
    382
    -			         RELAXED_LOAD_ALWAYS(&shared_current_tick));
    
    392
    +                   RELAXED_LOAD_ALWAYS(&shared_current_tick));
    
    383 393
             RELAXED_STORE_ALWAYS(&shared_idlegc_state, IDLEGC_STATE_PENDING);
    
    384 394
     #if defined(THREADED_RTS)
    
    385 395
             wakeUpRts();
    
    386 396
     #endif
    
    387 397
         } else {
    
    388 398
             debugTrace(DEBUG_idlegc, "Idle GC (tick %d): transition to DONE",
    
    389
    -			         RELAXED_LOAD_ALWAYS(&shared_current_tick));
    
    399
    +                   RELAXED_LOAD_ALWAYS(&shared_current_tick));
    
    390 400
             RELAXED_STORE_ALWAYS(&shared_idlegc_state, IDLEGC_STATE_DONE);
    
    391 401
         }
    
    392 402
     
    
    ... ... @@ -405,7 +415,7 @@ static void pauseTimerUnlessProfiling(void)
    405 415
     #endif
    
    406 416
         {
    
    407 417
             debugTrace(DEBUG_idlegc, "Idle GC (tick %d): pausing the ticker",
    
    408
    -			         RELAXED_LOAD_ALWAYS(&shared_current_tick));
    
    418
    +                                 RELAXED_LOAD_ALWAYS(&shared_current_tick));
    
    409 419
             stopTimer();
    
    410 420
     
    
    411 421
             /* Save the time at which we pause, so we can account for ticks missed
    

  • rts/Proftimer.c
    ... ... @@ -78,7 +78,10 @@ startHeapProfTimer( void )
    78 78
     
    
    79 79
     void
    
    80 80
     pauseHeapProfTimer ( void ) {
    
    81
    -    RELAXED_STORE_ALWAYS(&do_heap_prof_ticks, false);
    
    81
    +    if (RtsFlags.ProfFlags.doHeapProfile &&
    
    82
    +        RtsFlags.ProfFlags.heapProfileIntervalTicks > 0) {
    
    83
    +        RELAXED_STORE_ALWAYS(&do_heap_prof_ticks, false);
    
    84
    +    }
    
    82 85
     }
    
    83 86
     
    
    84 87
     
    

  • rts/RtsFlags.c
    ... ... @@ -1921,6 +1921,7 @@ static void normaliseRtsOpts (void)
    1921 1921
         if (RtsFlags.MiscFlags.tickInterval == 0) {
    
    1922 1922
             RtsFlags.ConcFlags.ctxtSwitchTime  = 0;
    
    1923 1923
             RtsFlags.GcFlags.idleGCDelayTime   = 0;
    
    1924
    +        RtsFlags.GcFlags.doIdleGC          = false;
    
    1924 1925
             RtsFlags.ProfFlags.heapProfileInterval = 0;
    
    1925 1926
         }
    
    1926 1927
     
    

  • rts/Schedule.c
    ... ... @@ -1403,9 +1403,9 @@ scheduleNeedHeapProfile( bool ready_to_gc )
    1403 1403
     {
    
    1404 1404
         // When we have +RTS -i0 and we're heap profiling, do a census at
    
    1405 1405
         // every GC.  This lets us get repeatable runs for debugging.
    
    1406
    -    if (RELAXED_LOAD(&performHeapProfile) ||
    
    1407
    -        (RtsFlags.ProfFlags.heapProfileInterval==0 &&
    
    1408
    -         RtsFlags.ProfFlags.doHeapProfile && ready_to_gc)) {
    
    1406
    +    if (RtsFlags.ProfFlags.doHeapProfile
    
    1407
    +        && ((RtsFlags.ProfFlags.heapProfileInterval==0 && ready_to_gc)
    
    1408
    +            || RELAXED_LOAD(&performHeapProfile))) {
    
    1409 1409
             return true;
    
    1410 1410
         } else {
    
    1411 1411
             return false;