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

[coop] Attach external native threads in GC Safe mode #31765

Closed

Conversation

monojenkins
Copy link
Contributor

@monojenkins monojenkins commented Feb 5, 2020

!! This PR is a copy of mono/mono#18708, please do not edit or review it in this repo !!
!! Merge the PR only after the original PR is merged !!



(Broke out the second part of mono/mono#18656 into a separate PR for easier reviewing and added a test case)

Mark mono_thread_attach external only. Runtime should use mono_thread_internal_attach.

The difference is that threads that are started on behalf of Mono will start in GC Unsafe mode, whereas external threads that attach to the runtime will be in GC Safe mode. This is consistent with how native-to-managed thunks behave, too. They will attach the thread and switch to GC Unsafe mode while running managed code, but will switch to GC Safe mode when they return. If the runtime needs to suspend one of these native threads while it's not running any runtime or managed code, it will use preemptive suspension under the hybrid (and full-async) suspend policy.

There is the orthogonal question of whether the attached thread will be foreground or background. This PR does not change the current behavior: if an external native thread calls a native-to-managed thunk it will be attached as a background thread. If it explicitly calls mono_thread_attach, it will be foreground.

Additionally, change mono_thread_detach to switch to GC Unsafe mode while calling mono_thread_detach_internal, to undo the effects of mono_thread_attach.

Switch external thread to GC Safe only if it wasn't already. If an embedder calls mono_thread_attach / mono_thread_detach themselves, the MonoThreadInfo* persists. And since the thread is external to the runtime, it is in GC Safe mode while it isn't calling into the runtime. So after the detach, if we try to re-attach it, performing a transition to GC Safe again will assert, since GC Safe mode doesn't nest.
Additionally, if we need to create the managed MonoInternalThread and MonoThread objects, we should do that in GC Unsafe mode, so add transitions to ensure that's the case.

(Broke out the second part of mono/mono#18656 into a separate PR for easier reviewing and added a test case)

Mark `mono_thread_attach` external only.  Runtime should use `mono_thread_internal_attach`.

The difference is that threads that are started on behalf of Mono will start in GC Unsafe mode, whereas external threads that attach to the runtime will be in GC Safe mode.  This is consistent with how native-to-managed thunks behave, too. They will attach the thread and switch to GC Unsafe mode while running managed code, but will switch to GC Safe mode when they return.  If the runtime needs to suspend one of these native threads while it's not running any runtime or managed code, it will use preemptive suspension under the hybrid (and full-async) suspend policy.

There is the orthogonal question of whether the attached thread will be foreground or background.  This PR does not change the current behavior: if an external native thread calls a native-to-managed thunk it will be attached as a background thread.  If it explicitly calls `mono_thread_attach`, it will be foreground.

Additionally, change `mono_thread_detach` to switch to GC Unsafe mode while calling `mono_thread_detach_internal`, to undo the effects of `mono_thread_attach`.

Switch external thread to GC Safe only if it wasn't already. If an embedder calls `mono_thread_attach` / `mono_thread_detach` themselves, the `MonoThreadInfo*` persists.  And since the thread is external to the runtime, it is in GC Safe mode while it isn't calling into the runtime.  So after the detach, if we try to re-attach it, performing a transition to GC Safe again will assert, since GC Safe mode doesn't nest.
Additionally, if we need to create the managed `MonoInternalThread` and `MonoThread` objects, we should do that in GC Unsafe mode, so add transitions to ensure that's the case.
@lambdageek lambdageek closed this Sep 25, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-VM-threading-mono NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants