Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement MONO_ENTER_NO_SAFEPOINTS/MONO_EXIT_NO_SAFEPOINTS (mono/mono…
…#11476) * [threads] Add a no_safepoints bit to the thread state machine. Only valid on RUNNING or ASYNC_SUSPEND_REQUESTED. Currently no transitions set the bit, but the expectation is that it can only be set/unset by the current thread on itself and only in RUNNING or ASYNC_SUSPEND_REQUESTED. Transitions to suspended states or to GC Safe states are forbidden if wont_safept is set. The intention is that this is used by a thread to mark a scope where it will not safepoint (perhaps because it wants to manipulate a raw ptr to a managed object). The wont_safept bit only makes sense for cooperative suspension. For async, we have the critical regions (which should be much more rarely needed). * [threads] Add state machine funcs to query/set/uniset wont_safept * [threads] add MONO_ENTER_NO_SAFEPOINTS/MONO_EXIT_NO_SAFEPOINTS macros A region between MONO_ENTER_NO_SAFEPOINTS/MONO_EXIT_NO_SAFEPOINTS must not call any function that could: reach a safepoint (and suspend the current thread), allocate memory from the managed heap, or transition to GC Safe. In such a region it is safe to dereference a pointer to managed memory and use read/write from it (an alternative to avoid the no safepoints region is to pin the memory with a global GC handle before manipulating it). GC Write barriers still need to be used. The current design doesn't allow nesting - the underlying thread state transitions check that the flag isn't already set - keep the regions short and simple. * [sgen] Don't initiate STW from a thread in a NO_SAFEPOINTS region In other words, if you were in MONO_ENTER_NO_SAFEPOINTS/MONO_EXIT_NO_SAFEPOINTS, you shouldn't be calling anything that would start the GC Commit migrated from mono/mono@d28db36
- Loading branch information