Skip to content
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

Delay marking of finished tasks #48037

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft

Delay marking of finished tasks #48037

wants to merge 1 commit into from

Conversation

vchuravy
Copy link
Member

Alternative proposal to #47829 intending to fix #40626

The idea is to skip non-runnable tasks during the inital
roots gathering phase. If someone has a reference to a finished
task we won't mess with the task fields.

After we are done with the primary marking phase, we check the
finished tasks and if they have not yet been marked we
set some of the fields we care about to nothing and then
enqueue the other fields.

I briefly thought about not enqueueing the other fields,
but thats much more invasive.

@JeffBezanson One field I would like to zero is the current
stkbuf, but that might be one we actually have to use?

@vchuravy vchuravy added the GC Garbage collector label Dec 29, 2022
@vchuravy vchuravy marked this pull request as draft December 29, 2022 10:59
@gbaraldi
Copy link
Member

So it turns the fields of the tasks into a kind of weak reference?

@vchuravy
Copy link
Member Author

vchuravy commented Jan 5, 2023

So it turns the fields of the tasks into a kind of weak reference?

Not quite, it turns the current_task field in ptls into a weak reference, if it is pointing to a task that is not runnable.

@vchuravy vchuravy marked this pull request as ready for review January 5, 2023 19:05
@d-netto
Copy link
Member

d-netto commented Jan 9, 2023

It would be nice to have a test like the one @NHDaly suggested in #47829.

@vchuravy
Copy link
Member Author

vchuravy commented Jan 9, 2023

@nanosoldier runtests()

@vchuravy
Copy link
Member Author

vchuravy commented Jan 9, 2023

The problem is that the tests are very indirect. The issue is that ptls->current_task keeps a reference to a done task, thus increasing the life-time of objects referenced by that task.

function foo(x::Vector)
    @async length(x)
end
a = []
r = WeakRef(a)
t = foo(a)
a = nothing
wait(t)
GC.gc()
@test r.value === nothing

Would have worked in my previous attempt, but does not test the issue at hand since t won't be a ptls->current_Task.

@nanosoldier
Copy link
Collaborator

Your package evaluation job has completed - possible new issues were detected.
A full report can be found here.

Copy link
Member

@vtjnash vtjnash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems possibly not quite sound yet, since one deferred-marked task might refer to another task, making it so you cannot sweep and mark at the same time

@NHDaly
Copy link
Member

NHDaly commented May 8, 2023

This seems possibly not quite sound yet, since one deferred-marked task might refer to another task, making it so you cannot sweep and mark at the same time

@vtjnash: If the two tasks you mention here are both non-runnable, meaning that they are only referenced through what we now consider a weak-reference, doesn't it not matter if one references the other? They can both be collected now since the only reference to them is weak?

I'm also not following what you mean by "sweep and mark at the same time" - is that specific to the implementation details in the PR? I didn't read it closely yet.

@apieum
Copy link

apieum commented May 15, 2023

The problem is that the tests are very indirect. The issue is that ptls->current_task keeps a reference to a done task, thus increasing the life-time of objects referenced by that task.

function foo(x::Vector)
    @async length(x)
end
a = []
r = WeakRef(a)
t = foo(a)
a = nothing
wait(t)
GC.gc()
@test r.value === nothing

Would have worked in my previous attempt, but does not test the issue at hand since t won't be a ptls->current_Task.

This wouldn't work due to weakref behavior (bug ?). If you get value from a weakref, it keeps it.

a = []
r = WeakRef(a)
r.value #if you comment this line the tests pass
a = nothing
GC.gc()
@test a === nothing # this one passes
@test r.value === nothing # this one fails
weakref: Test Failed at ...
   Expression: r.value === nothing
   Evaluated: Any[] === nothing

@quinnj
Copy link
Member

quinnj commented Aug 14, 2023

Any update on this? Any possible resolution to @vtjnash's concern @vchuravy?

@vchuravy
Copy link
Member Author

I currently don't have the availability to continue work on this.

@vchuravy vchuravy marked this pull request as draft October 28, 2023 18:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GC Garbage collector
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Thread-local current_task keeps garbage alive
8 participants