return TRUE;
}
- return mono_threads_core_begin_async_suspend (info, interrupt_kernel);
+ return mono_threads_suspend_begin_async_suspend (info, interrupt_kernel);
}
static gboolean
return TRUE;
}
- return mono_threads_core_check_suspend_result (info);
+ return mono_threads_suspend_check_suspend_result (info);
}
static void
if (mono_threads_is_coop_enabled ())
g_assert_not_reached ();
- g_assert (mono_threads_core_begin_async_resume (info));
+ g_assert (mono_threads_suspend_begin_async_resume (info));
}
static void
MonoThreadInfo*
mono_thread_info_lookup (MonoNativeThreadId id)
{
- MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
+ MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
- if (!mono_lls_find (&thread_list, hp, (uintptr_t)id, HAZARD_FREE_ASYNC_CTX)) {
+ if (!mono_lls_find (&thread_list, hp, (uintptr_t)id)) {
mono_hazard_pointer_clear_all (hp, -1);
return NULL;
}
{
MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
- if (!mono_lls_insert (&thread_list, hp, (MonoLinkedListSetNode*)info, HAZARD_FREE_SAFE_CTX)) {
+ if (!mono_lls_insert (&thread_list, hp, (MonoLinkedListSetNode*)info)) {
mono_hazard_pointer_clear_all (hp, -1);
return FALSE;
}
gboolean res;
THREADS_DEBUG ("removing info %p\n", info);
- res = mono_lls_remove (&thread_list, hp, (MonoLinkedListSetNode*)info, HAZARD_FREE_SAFE_CTX);
+ res = mono_lls_remove (&thread_list, hp, (MonoLinkedListSetNode*)info);
mono_hazard_pointer_clear_all (hp, -1);
return res;
}
MonoThreadInfo *info = (MonoThreadInfo *) mem;
mono_os_sem_destroy (&info->resume_semaphore);
- mono_threads_platform_free (info);
+ mono_threads_suspend_free (info);
g_free (info);
}
info->stackdata = g_byte_array_new ();
mono_threads_platform_register (info);
+ mono_threads_suspend_register (info);
/*
Transition it before taking any locks or publishing itself to reduce the chance
info = (MonoThreadInfo *) arg;
g_assert (info);
+ g_assert (mono_thread_info_is_current (info));
+ g_assert (mono_thread_info_is_live (info));
small_id = info->small_id;
mono_native_tls_set_value (thread_exited_key, GUINT_TO_POINTER (1));
- mono_threads_core_unregister (info);
+ mono_threads_platform_unregister (info);
/*
* TLS destruction order is not reliable so small_id might be cleaned up
return FALSE;
}
+#ifndef HOST_WIN32
+static void
+thread_info_key_dtor (void *arg)
+{
+ /* Put the MonoThreadInfo back for the duration of the
+ * unregister code. In some circumstances the thread needs to
+ * take the GC lock which may block which requires a coop
+ * state transition. */
+ mono_native_tls_set_value (thread_info_key, arg);
+ unregister_thread (arg);
+ mono_native_tls_set_value (thread_info_key, NULL);
+}
+#endif
+
void
mono_threads_init (MonoThreadInfoCallbacks *callbacks, size_t info_size)
{
res = mono_native_tls_alloc (&thread_info_key, NULL);
res = mono_native_tls_alloc (&thread_exited_key, NULL);
#else
- res = mono_native_tls_alloc (&thread_info_key, (void *) unregister_thread);
+ res = mono_native_tls_alloc (&thread_info_key, (void *) thread_info_key_dtor);
res = mono_native_tls_alloc (&thread_exited_key, (void *) thread_exited_dtor);
#endif
mono_os_sem_init (&global_suspend_semaphore, 1);
mono_os_sem_init (&suspend_semaphore, 0);
- mono_lls_init (&thread_list, NULL, HAZARD_FREE_NO_LOCK);
+ mono_lls_init (&thread_list, NULL);
mono_thread_smr_init ();
- mono_threads_init_platform ();
- mono_threads_init_coop ();
- mono_threads_init_abort_syscall ();
+ mono_threads_platform_init ();
+ mono_threads_suspend_init ();
+ mono_threads_coop_init ();
+ mono_threads_abort_syscall_init ();
#if defined(__MACH__)
mono_mach_init (thread_info_key);
mono_thread_info_core_resume (MonoThreadInfo *info)
{
gboolean res = FALSE;
- if (info->create_suspended) {
- MonoNativeThreadId tid = mono_thread_info_get_tid (info);
- /* Have to special case this, as the normal suspend/resume pair are racy, they don't work if he resume is received before the suspend */
- info->create_suspended = FALSE;
- mono_threads_core_resume_created (info, tid);
- return TRUE;
- }
switch (mono_threads_transition_request_resume (info)) {
case ResumeError:
break;
case AsyncSuspendBlocking:
if (interrupt_kernel)
- mono_threads_core_abort_syscall (info);
+ mono_threads_suspend_abort_syscall (info);
break;
default:
mono_thread_info_suspend_lock_with_info (MonoThreadInfo *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);
MonoThreadHazardPointers *hp;
MonoThreadInfo *info;
- if (tid == mono_native_thread_id_get () || !mono_threads_core_needs_abort_syscall ())
+ if (tid == mono_native_thread_id_get () || !mono_threads_suspend_needs_abort_syscall ())
return;
hp = mono_hazard_pointer_get ();
mono_thread_info_suspend_lock ();
mono_threads_begin_global_suspend ();
- mono_threads_core_abort_syscall (info);
+ mono_threads_suspend_abort_syscall (info);
mono_threads_wait_pending_operations ();
mono_hazard_pointer_clear (hp, 1);
return FALSE;
}
+typedef struct {
+ gint32 ref;
+ MonoThreadStart start_routine;
+ gpointer start_routine_arg;
+ gint32 priority;
+ MonoCoopSem registered;
+ gpointer handle;
+} CreateThreadData;
+
+static gsize WINAPI
+inner_start_thread (gpointer data)
+{
+ CreateThreadData *thread_data;
+ MonoThreadInfo *info;
+ MonoThreadStart start_routine;
+ gpointer start_routine_arg;
+ guint32 start_routine_res;
+ gsize dummy;
+
+ thread_data = (CreateThreadData*) data;
+ g_assert (thread_data);
+
+ start_routine = thread_data->start_routine;
+ start_routine_arg = thread_data->start_routine_arg;
+
+ info = mono_thread_info_attach (&dummy);
+ info->runtime_thread = TRUE;
+
+ thread_data->handle = mono_thread_info_duplicate_handle (info);
+
+ mono_coop_sem_post (&thread_data->registered);
+
+ if (InterlockedDecrement (&thread_data->ref) == 0) {
+ mono_coop_sem_destroy (&thread_data->registered);
+ g_free (thread_data);
+ }
+
+ /* thread_data is not valid anymore */
+ thread_data = NULL;
+
+ /* Run the actual main function of the thread */
+ start_routine_res = start_routine (start_routine_arg);
+
+ mono_threads_platform_exit (start_routine_res);
+
+ g_assert_not_reached ();
+}
+
/*
* mono_threads_create_thread:
*
* Returns: a windows or io-layer handle for the thread.
*/
HANDLE
-mono_threads_create_thread (LPTHREAD_START_ROUTINE start, gpointer arg, MonoThreadParm *tp, MonoNativeThreadId *out_tid)
-{
- return mono_threads_core_create_thread (start, arg, tp, out_tid);
+mono_threads_create_thread (MonoThreadStart start, gpointer arg, gsize stack_size, MonoNativeThreadId *out_tid)
+{
+ CreateThreadData *thread_data;
+ gint res;
+ gpointer ret;
+
+ thread_data = g_new0 (CreateThreadData, 1);
+ thread_data->ref = 2;
+ thread_data->start_routine = start;
+ thread_data->start_routine_arg = arg;
+ mono_coop_sem_init (&thread_data->registered, 0);
+
+ res = mono_threads_platform_create_thread (inner_start_thread, (gpointer) thread_data, stack_size, out_tid);
+ if (res != 0) {
+ /* ref is not going to be decremented in inner_start_thread */
+ InterlockedDecrement (&thread_data->ref);
+ ret = NULL;
+ goto done;
+ }
+
+ res = mono_coop_sem_wait (&thread_data->registered, MONO_SEM_FLAGS_NONE);
+ g_assert (res == 0);
+
+ ret = thread_data->handle;
+ g_assert (ret);
+
+done:
+ if (InterlockedDecrement (&thread_data->ref) == 0) {
+ mono_coop_sem_destroy (&thread_data->registered);
+ g_free (thread_data);
+ }
+
+ return ret;
}
/*
mono_thread_info_get_stack_bounds (guint8 **staddr, size_t *stsize)
{
guint8 *current = (guint8 *)&stsize;
- mono_threads_core_get_stack_bounds (staddr, stsize);
+ mono_threads_platform_get_stack_bounds (staddr, stsize);
if (!*staddr)
return;
gboolean
mono_thread_info_yield (void)
{
- return mono_threads_core_yield ();
+ return mono_threads_platform_yield ();
}
static mono_lazy_init_t sleep_init = MONO_LAZY_INIT_STATUS_NOT_INITIALIZED;
static MonoCoopMutex sleep_mutex;
*alerted = FALSE;
if (ms != INFINITE)
- end = mono_100ns_ticks () + (ms * 1000 * 10);
+ end = mono_msec_ticks() + ms;
mono_lazy_initialize (&sleep_init, sleep_initialize);
for (;;) {
if (ms != INFINITE) {
- now = mono_100ns_ticks ();
- if (now > end)
+ now = mono_msec_ticks();
+ if (now >= end)
break;
}
}
if (ms != INFINITE)
- mono_coop_cond_timedwait (&sleep_cond, &sleep_mutex, (end - now) / 10 / 1000);
+ mono_coop_cond_timedwait (&sleep_cond, &sleep_mutex, end - now);
else
mono_coop_cond_wait (&sleep_cond, &sleep_mutex);
void
mono_thread_info_exit (void)
{
- mono_threads_core_exit (0);
-}
-
-/*
- * mono_thread_info_open_handle:
- *
- * Return a io-layer/win32 handle for the current thread.
- * The handle need to be closed by calling CloseHandle () when it is no
- * longer needed.
- */
-HANDLE
-mono_thread_info_open_handle (void)
-{
- return mono_threads_core_open_handle ();
+ mono_threads_platform_exit (0);
}
/*
HANDLE
mono_threads_open_thread_handle (HANDLE handle, MonoNativeThreadId tid)
{
- return mono_threads_core_open_thread_handle (handle, tid);
+ return mono_threads_platform_open_thread_handle (handle, tid);
+}
+
+void
+mono_threads_close_thread_handle (HANDLE handle)
+{
+ return mono_threads_platform_close_thread_handle (handle);
}
#define INTERRUPT_STATE ((MonoThreadInfoInterruptToken*) (size_t) -1)
{
return mono_thread_info_get_tid (info) == mono_native_thread_id_get ();
}
+
+void
+mono_thread_info_set_exited (THREAD_INFO_TYPE *info)
+{
+ g_assert (mono_thread_info_is_current (info));
+ mono_threads_platform_set_exited (info);
+}
+
+gpointer
+mono_thread_info_duplicate_handle (MonoThreadInfo *info)
+{
+ g_assert (mono_thread_info_is_current (info));
+ return mono_threads_platform_duplicate_handle (info);
+}
+
+void
+mono_thread_info_own_mutex (MonoThreadInfo *info, gpointer mutex_handle)
+{
+ mono_threads_platform_own_mutex (info, mutex_handle);
+}
+
+void
+mono_thread_info_disown_mutex (MonoThreadInfo *info, gpointer mutex_handle)
+{
+ mono_threads_platform_disown_mutex (info, mutex_handle);
+}