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.

@monojenkins monojenkins force-pushed the sync-pr-18708-from-mono branch 3 times, most recently from ede39a3 to d5368e6 Compare February 5, 2020 21:16
@monojenkins monojenkins force-pushed the sync-pr-18708-from-mono branch 8 times, most recently from be7edef to 2a4ad7c Compare February 11, 2020 22:08
@monojenkins monojenkins force-pushed the sync-pr-18708-from-mono branch from 2a4ad7c to 030b92e Compare September 23, 2020 19:50
@lambdageek lambdageek marked this pull request as draft September 24, 2020 13:33
@lambdageek lambdageek added the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Sep 24, 2020
(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.
@monojenkins monojenkins force-pushed the sync-pr-18708-from-mono branch from 030b92e to ecd024c Compare September 24, 2020 20:38
@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