| ... |
... |
@@ -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
|