Skip to content

Commit

Permalink
Fix GC pacing problem exacerbated by mark-delay (#3331)
Browse files Browse the repository at this point in the history
Band-aid for GC pacing problem discovered while upstreaming mark-delay to ocaml/ocaml#13580.
  • Loading branch information
NickBarnes authored Dec 3, 2024
1 parent 7e20367 commit aded4b5
Showing 1 changed file with 21 additions and 0 deletions.
21 changes: 21 additions & 0 deletions runtime/major_gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,27 @@ static void update_major_slice_work(intnat howmuch,
atomic_fetch_add (&work_counter, dom_st->major_work_done_between_slices);
dom_st->major_work_done_between_slices = 0;
atomic_fetch_add (&alloc_counter, new_work);

/* If the work_counter is falling far behind the alloc_counter,
* artificially catch up some of the difference. This is a band-aid
* for general GC pacing problems revealed by the mark-delay changes
* (see comments on ocaml/ocaml PR #13580): when we rework the
* pacing this should go away. */
int64_t pending = diffmod(atomic_load(&alloc_counter),
atomic_load(&work_counter));
if (pending > (int64_t)total_cycle_work * 2) {
intnat catchup = pending - total_cycle_work;
caml_gc_message(0x40,
"work counter %"ARCH_INTNAT_PRINTF_FORMAT"u falling behind "
"alloc counter %"ARCH_INTNAT_PRINTF_FORMAT"u by more than "
"twice a total cycle's work %"ARCH_INTNAT_PRINTF_FORMAT"d; "
"catching up by %"ARCH_INTNAT_PRINTF_FORMAT "d\n",
atomic_load(&work_counter),
atomic_load(&alloc_counter),
total_cycle_work, catchup);
atomic_fetch_add (&work_counter, catchup);
}

if (howmuch == AUTO_TRIGGERED_MAJOR_SLICE ||
howmuch == GC_CALCULATE_MAJOR_SLICE) {
dom_st->slice_target = atomic_load (&alloc_counter);
Expand Down

0 comments on commit aded4b5

Please sign in to comment.