-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scheduler: Use the root task as a scheduler task #57465
base: master
Are you sure you want to change the base?
Conversation
assert(jl_atomic_load_relaxed(&ct->_state) == JL_TASK_STATE_RUNNABLE); | ||
return ct; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we can/should delay this task switch even more?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that I think of it, we can refactor this slighly. The sleep atomics only make sense after we switched to the root task. And it can/should go to sleep as soon as it checks, theres no need for it to spin since we're guaranteed to have already spun before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're saying we should move this to the top of the if
block, before switching sleep_check_state
to sleeping
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, I moved this code block ahead of the atomics and added a condition to the if
to avoid sleep checking twice.
Why is this? |
Thread 1s root task actually does stuff like run the REPL/toplevel code. So it's a |
I considered creating a new task in |
e05ce1a
to
5993983
Compare
Could we make the root task on thread 1, do nothing but launch a task that does the work it used to do, and thus it becomes the scheduler task? |
We can. It gets complicated though, because we have to return from Am I understanding your suggestion correctly? |
A Julia thread runs Julia's scheduler in the context of the switching task. If no task is found to switch to, the thread will sleep while holding onto the (possibly completed) task, preventing the task from being garbage collected. This recent Discourse post illustrates precisely this problem.
A solution to this would be for an idle Julia thread to switch to a "scheduler" task, thereby freeing the old task.
Other than thread 1, the root task that is created for every Julia-started (non-GC) thread essentially ends immediately -- we call
jl_finish_task
at the end ofjl_threadfun
.This PR uses root tasks (on all but thread 1) as scheduler tasks. This solves the problem for all but thread 1. We could do the same for thread 1 also, but it would require special-casing as we cannot use thread 1's root task for this purpose.