#include <mono/utils/mono-threads-coop.h>
#include <mono/utils/mono-threads-debug.h>
#include <mono/utils/os-event.h>
+#include <mono/utils/w32api.h>
#include <errno.h>
static MonoThreadInfoRuntimeCallbacks runtime_callbacks;
static MonoNativeTlsKey thread_info_key, thread_exited_key;
#ifdef HAVE_KW_THREAD
-static __thread guint32 tls_small_id MONO_TLS_FAST;
+static __thread guint32 tls_small_id;
#else
static MonoNativeTlsKey small_id_key;
#endif
static MonoSemType suspend_semaphore;
static size_t pending_suspends;
+static mono_mutex_t join_mutex;
+
#define mono_thread_info_run_state(info) (((MonoThreadInfo*)info)->thread_state & THREAD_STATE_MASK)
/*warn at 50 ms*/
g_assert (mono_thread_info_is_current (info));
g_assert (mono_thread_info_is_live (info));
+ /* Pump the HP queue while the thread is alive.*/
+ mono_thread_hazardous_try_free_some ();
+
small_id = info->small_id;
/* We only enter the GC unsafe region, as when exiting this function, the thread
/*now it's safe to free the thread info.*/
mono_thread_hazardous_try_free (info, free_thread_info);
- /* Pump the HP queue */
- mono_thread_hazardous_try_free_some ();
mono_thread_small_id_free (small_id);
mono_os_sem_init (&global_suspend_semaphore, 1);
mono_os_sem_init (&suspend_semaphore, 0);
+ mono_os_mutex_init (&join_mutex);
mono_lls_init (&thread_list, NULL);
mono_thread_smr_init ();
mono_threads_suspend_init ();
- mono_threads_suspend_init_signals ();
mono_threads_coop_init ();
+ mono_threads_platform_init ();
#if defined(__MACH__)
mono_mach_init (thread_info_key);
g_assert (sizeof (MonoNativeThreadId) <= sizeof (uintptr_t));
}
+void
+mono_threads_signals_init (void)
+{
+ mono_threads_suspend_init_signals ();
+}
+
void
mono_threads_runtime_init (MonoThreadInfoRuntimeCallbacks *callbacks)
{
gpointer stack_start;
MonoThreadUnwindState *state;
+ if (mono_threads_platform_in_critical_region (mono_thread_info_get_tid (info)))
+ return TRUE;
+
/* Are we inside a system critical region? */
if (info->inside_critical_region)
return TRUE;
{
return mono_threads_platform_yield ();
}
+
static mono_lazy_init_t sleep_init = MONO_LAZY_INIT_STATUS_NOT_INITIALIZED;
static MonoCoopMutex sleep_mutex;
static MonoCoopCond sleep_cond;
else
g_error ("%s: unknown res value %d", __func__, res);
}
+
+/*
+ * mono_threads_join_mutex:
+ *
+ * This mutex is used to avoid races between pthread_create () and pthread_join () on osx, see
+ * https://bugzilla.xamarin.com/show_bug.cgi?id=50529
+ * The code inside the lock should not block.
+ */
+void
+mono_threads_join_lock (void)
+{
+#ifdef TARGET_OSX
+ mono_os_mutex_lock (&join_mutex);
+#endif
+}
+
+void
+mono_threads_join_unlock (void)
+{
+#ifdef TARGET_OSX
+ mono_os_mutex_unlock (&join_mutex);
+#endif
+}