static MonoThreadInfoRuntimeCallbacks runtime_callbacks;
static MonoNativeTlsKey thread_info_key, thread_exited_key;
#ifdef HAVE_KW_THREAD
-static __thread guint32 tls_small_id;
+static __thread gint32 tls_small_id = -1;
#else
static MonoNativeTlsKey small_id_key;
#endif
g_free (info);
}
+/*
+ * mono_thread_info_register_small_id
+ *
+ * Registers a small ID for the current thread. This is a 16-bit value uniquely
+ * identifying the current thread. If the current thread already has a small ID
+ * assigned, that small ID will be returned; otherwise, the newly assigned small
+ * ID is returned.
+ */
int
mono_thread_info_register_small_id (void)
{
- int small_id = mono_thread_small_id_alloc ();
+ int small_id = mono_thread_info_get_small_id ();
+
+ if (small_id != -1)
+ return small_id;
+
+ small_id = mono_thread_small_id_alloc ();
#ifdef HAVE_KW_THREAD
tls_small_id = small_id;
#else
info->internal_thread_gchandle = G_MAXUINT32;
+ info->profiler_signal_ack = 1;
+
mono_threads_suspend_register (info);
THREADS_DEBUG ("registering info %p tid %p small id %x\n", info, mono_thread_info_get_tid (info), info->small_id);
return info;
}
+/*
+ * mono_thread_info_get_small_id
+ *
+ * Retrieve the small ID for the current thread. This is a 16-bit value uniquely
+ * identifying the current thread. Returns -1 if the current thread doesn't have
+ * a small ID assigned.
+ *
+ * To ensure that the calling thread has a small ID assigned, call either
+ * mono_thread_info_attach or mono_thread_info_register_small_id.
+ */
int
mono_thread_info_get_small_id (void)
{
if (interrupt_kernel)
mono_threads_suspend_abort_syscall (info);
- break;
+ return info;
default:
g_assert_not_reached ();
}
static void
mono_thread_info_suspend_lock_with_info (MonoThreadInfo *info)
{
- if (mono_threads_is_coop_enabled ()) {
- g_assert (info);
- g_assert (mono_thread_info_is_current (info));
- g_assert (mono_thread_info_is_live (info));
+ g_assert (info);
+ g_assert (mono_thread_info_is_current (info));
+ g_assert (mono_thread_info_is_live (info));
- MONO_ENTER_GC_SAFE_WITH_INFO(info);
+ MONO_ENTER_GC_SAFE_WITH_INFO(info);
- int res = mono_os_sem_wait (&global_suspend_semaphore, MONO_SEM_FLAGS_NONE);
- g_assert (res != -1);
+ int res = mono_os_sem_wait (&global_suspend_semaphore, MONO_SEM_FLAGS_NONE);
+ g_assert (res != -1);
- MONO_EXIT_GC_SAFE_WITH_INFO;
- } else {
- int res = mono_os_sem_wait (&global_suspend_semaphore, MONO_SEM_FLAGS_NONE);
- g_assert (res != -1);
- }
+ MONO_EXIT_GC_SAFE_WITH_INFO;
}
void
mono_thread_info_suspend_lock (void)
{
- mono_thread_info_suspend_lock_with_info (mono_thread_info_current_unchecked ());
+ MonoThreadInfo *info;
+ gint res;
+
+ info = mono_thread_info_current_unchecked ();
+ if (info && mono_thread_info_is_live (info)) {
+ mono_thread_info_suspend_lock_with_info (info);
+ return;
+ }
+
+ /* mono_thread_info_suspend_lock () can be called from boehm-gc.c on_gc_notification before the new thread's
+ * start_wrapper calls mono_thread_info_attach but after pthread_create calls the start wrapper. */
+
+ res = mono_os_sem_wait (&global_suspend_semaphore, MONO_SEM_FLAGS_NONE);
+ g_assert (res != -1);
}
void
} while (1);
} else {
int ret;
-#if defined (__linux__) && !defined(PLATFORM_ANDROID)
+#if defined (__linux__) && !defined(HOST_ANDROID)
struct timespec start, target;
/* Use clock_nanosleep () to prevent time drifting problems when nanosleep () is interrupted by signals */