Skip to content

Commit

Permalink
julia_gc: fix detection of already canned root task
Browse files Browse the repository at this point in the history
We already scan some stack during as part of the `GapRootScanner`
callback, which usually will be the stack of the active task of
the main thread. As an optimization, we want to avoid scanning
that task's thread a second time in `GapTaskScanner`.

We used to do that by checking in the latter whether the task
about to be scanned is the current task. But that is wrong:
the task may be different for all kinds of reasons, most notably
if there are multiple GC threads active.

So instead, just record the task we scanned in `GapRootScanner`
(this is safe to write as there is single thread involved at this
point) and then compare against that in `GapTaskScanner` (which
may be called concurrently from multiple threads).
  • Loading branch information
fingolfin committed May 27, 2024
1 parent 7e07b99 commit 4084a56
Showing 1 changed file with 7 additions and 3 deletions.
10 changes: 7 additions & 3 deletions src/julia_gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ static size_t MaxPoolObjSize;
static int FullGC;
static UInt StartTime, TotalTime;

static jl_task_t * ScannedRootTask;

#ifdef SKIP_GUARD_PAGES
static size_t GuardPageSize;
#endif
Expand Down Expand Up @@ -565,6 +567,8 @@ static void GapRootScanner(int full)
jl_ptls_t ptls = jl_get_ptls_states();
jl_task_t * task = (jl_task_t *)jl_get_current_task();

ScannedRootTask = task;

// We figure out the end of the stack from the current task. While
// `stack_bottom` is passed to InitBags(), we cannot use that if
// current_task != root_task.
Expand Down Expand Up @@ -615,9 +619,8 @@ static void GapRootScanner(int full)
// Julia callback
static void GapTaskScanner(jl_task_t * task, int root_task)
{
// If it is the current task, it has been scanned by GapRootScanner()
// already.
if (task == (jl_task_t *)jl_get_current_task())
// If this task has been scanned by GapRootScanner() already, skip it
if (task == ScannedRootTask)
return;

int rescan = 1;
Expand Down Expand Up @@ -689,6 +692,7 @@ static void PreGCHook(int full)
// Julia callback
static void PostGCHook(int full)
{
ScannedRootTask = 0;
TotalTime += SyTime() - StartTime;
#ifdef COLLECT_MARK_CACHE_STATS
/* printf("\n>>>Attempts: %ld\nHit rate: %lf\nCollision rate: %lf\n",
Expand Down

0 comments on commit 4084a56

Please sign in to comment.