From 6ac11972db9d6e0f5eadf51390c3dae0a0478b63 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Fri, 6 Dec 2019 23:56:10 +0100 Subject: [PATCH] [2019-10] [threads] Add back mono_threads_attach_tools_thread as a public API (#18075) * [utils] Add back mono_threads_attach_tools_thread In https://github.com/mono/mono/commit/a5da7b21f4b6dbc5eaa09c2addee91b84dc1dbd5 we got rid of "tools" threads internally to the runtime. However since the API was previously marked with MONO_API it was an internal API that some embedders depended on. This PR adds back an (external-only) limited form of tools thread. The runtime is aware of the Tools thread in that FOREACH_THREAD_* macros will iterate over them, and the thread has a coop thread state machine. (That is, mono_thread_info_current() and GC Safe and GC Unsafe transitions all work.) However the thread is: 1. Not stopped by the GC 2. Is not interrupted by profiler sampling. 3. Does not have a "current domain" 4. (As a consequence of the above) cannot call managed methods or touch managed objects. Such threads are useful for low-level interaction with the runtime such as querying metadata, the JIT state and other coordination. mono_threads_attach_tools_thread should be called no more than once. It should not be called on a thread that is already attached with mono_thread_atach, and vice versa. Addresses https://github.com/mono/mono/issues/18011 * [threads] Make mono_threads_attach_tools_thread into a public API --- mono/metadata/threads.c | 30 ++++++++++++++++++++++++++++++ mono/metadata/threads.h | 3 +++ 2 files changed, 33 insertions(+) diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c index e68692e723d0..6183c9591fe7 100644 --- a/mono/metadata/threads.c +++ b/mono/metadata/threads.c @@ -1549,6 +1549,34 @@ mono_thread_attach (MonoDomain *domain) return thread; } +/** + * mono_threads_attach_tools_thread: + * + * Attach the current thread as a tool thread. DON'T USE THIS FUNCTION WITHOUT READING ALL DISCLAIMERS. + * + * A tools thread is a very special kind of thread that needs access to core + * runtime facilities but should not be counted as a regular thread for high + * order facilities such as executing managed code or accessing the managed + * heap. + * + * This is intended only for low-level utilities than need to be able to use + * some low-level runtime facilities when doing things like resolving + * backtraces in their background processing thread. + * + * Note in particular that the thread is not fully attached - it does not have + * a "current domain" because it cannot run managed code or interact with + * managed objects. However it can act on some metadata, and use our low-level + * locks and the coop thread state machine (ie GC Safe and GC Unsafe + * transitions make sense). + */ +void +mono_threads_attach_tools_thread (void) +{ + MonoThreadInfo *info = mono_thread_info_attach (); + g_assert (info); + mono_thread_info_set_flags (MONO_THREAD_INFO_FLAGS_NO_GC | MONO_THREAD_INFO_FLAGS_NO_SAMPLE); +} + /** * mono_thread_detach: */ @@ -1559,6 +1587,8 @@ mono_thread_detach (MonoThread *thread) mono_thread_detach_internal (thread->internal_thread); } + + /** * mono_thread_detach_if_exiting: * diff --git a/mono/metadata/threads.h b/mono/metadata/threads.h index 52d76d8b69e3..b1b9103cd387 100644 --- a/mono/metadata/threads.h +++ b/mono/metadata/threads.h @@ -44,6 +44,9 @@ MONO_API MonoThread *mono_thread_attach (MonoDomain *domain); MONO_API void mono_thread_detach (MonoThread *thread); MONO_API void mono_thread_exit (void); +MONO_API MONO_RT_EXTERNAL_ONLY void +mono_threads_attach_tools_thread (void); + MONO_API char *mono_thread_get_name_utf8 (MonoThread *thread); MONO_API int32_t mono_thread_get_managed_id (MonoThread *thread);