Merge pull request #2034 from alexrp/ctx-cleanup
[mono.git] / mono / metadata / threads.c
index 6dc723925b13e48635351bb6a9b24463d2b6c7fe..112c8779454ed5ef48ce13245dd4e04ada9483d5 100644 (file)
@@ -24,7 +24,7 @@
 #include <mono/metadata/exception.h>
 #include <mono/metadata/environment.h>
 #include <mono/metadata/monitor.h>
-#include <mono/metadata/gc-internal.h>
+#include <mono/metadata/gc-internals.h>
 #include <mono/metadata/marshal.h>
 #include <mono/metadata/runtime.h>
 #include <mono/io-layer/io-layer.h>
@@ -41,7 +41,7 @@
 #include <mono/utils/atomic.h>
 #include <mono/utils/mono-memory-model.h>
 
-#include <mono/metadata/gc-internal.h>
+#include <mono/metadata/gc-internals.h>
 
 #ifdef HAVE_SIGNAL_H
 #include <signal.h>
@@ -128,11 +128,11 @@ typedef struct {
 /* Controls access to the 'threads' hash table */
 static void mono_threads_lock (void);
 static void mono_threads_unlock (void);
-static mono_mutex_t threads_mutex;
+static MonoCoopMutex threads_mutex;
 
 /* Controls access to the 'joinable_threads' hash table */
-#define joinable_threads_lock() mono_mutex_lock (&joinable_threads_mutex)
-#define joinable_threads_unlock() mono_mutex_unlock (&joinable_threads_mutex)
+#define joinable_threads_lock() mono_os_mutex_lock (&joinable_threads_mutex)
+#define joinable_threads_unlock() mono_os_mutex_unlock (&joinable_threads_mutex)
 static mono_mutex_t joinable_threads_mutex;
 
 /* Holds current status of static data heap */
@@ -207,14 +207,13 @@ static gboolean mono_thread_resume (MonoInternalThread* thread);
 static void abort_thread_internal (MonoInternalThread *thread, gboolean can_raise_exception, gboolean install_async_abort);
 static void suspend_thread_internal (MonoInternalThread *thread, gboolean interrupt);
 static void self_suspend_internal (MonoInternalThread *thread);
-static gboolean resume_thread_internal (MonoInternalThread *thread);
 
 static MonoException* mono_thread_execute_interruption ();
 static void ref_stack_destroy (gpointer rs);
 
 /* Spin lock for InterlockedXXX 64 bit functions */
-#define mono_interlocked_lock() mono_mutex_lock (&interlocked_mutex)
-#define mono_interlocked_unlock() mono_mutex_unlock (&interlocked_mutex)
+#define mono_interlocked_lock() mono_os_mutex_lock (&interlocked_mutex)
+#define mono_interlocked_unlock() mono_os_mutex_unlock (&interlocked_mutex)
 static mono_mutex_t interlocked_mutex;
 
 /* global count of thread interruptions requested */
@@ -230,15 +229,13 @@ static gint32 managed_thread_id_counter = 0;
 static void
 mono_threads_lock (void)
 {
-       MONO_TRY_BLOCKING;
-       mono_locks_acquire (&threads_mutex, ThreadsLock);
-       MONO_FINISH_TRY_BLOCKING;
+       mono_locks_coop_acquire (&threads_mutex, ThreadsLock);
 }
 
 static void
 mono_threads_unlock (void)
 {
-       mono_locks_release (&threads_mutex, ThreadsLock);
+       mono_locks_coop_release (&threads_mutex, ThreadsLock);
 }
 
 
@@ -352,19 +349,19 @@ static gboolean handle_remove(MonoInternalThread *thread)
 
 static void ensure_synch_cs_set (MonoInternalThread *thread)
 {
-       mono_mutex_t *synch_cs;
+       MonoCoopMutex *synch_cs;
 
        if (thread->synch_cs != NULL) {
                return;
        }
 
-       synch_cs = g_new0 (mono_mutex_t, 1);
-       mono_mutex_init_recursive (synch_cs);
+       synch_cs = g_new0 (MonoCoopMutex, 1);
+       mono_coop_mutex_init_recursive (synch_cs);
 
        if (InterlockedCompareExchangePointer ((gpointer *)&thread->synch_cs,
                                               synch_cs, NULL) != NULL) {
                /* Another thread must have installed this CS */
-               mono_mutex_destroy (synch_cs);
+               mono_coop_mutex_destroy (synch_cs);
                g_free (synch_cs);
        }
 }
@@ -377,15 +374,13 @@ lock_thread (MonoInternalThread *thread)
 
        g_assert (thread->synch_cs);
 
-       MONO_TRY_BLOCKING;
-       mono_mutex_lock (thread->synch_cs);
-       MONO_FINISH_TRY_BLOCKING;
+       mono_coop_mutex_lock (thread->synch_cs);
 }
 
 static inline void
 unlock_thread (MonoInternalThread *thread)
 {
-       mono_mutex_unlock (thread->synch_cs);
+       mono_coop_mutex_unlock (thread->synch_cs);
 }
 
 /*
@@ -484,6 +479,7 @@ static void thread_cleanup (MonoInternalThread *thread)
                MONO_GC_UNREGISTER_ROOT (thread->thread_pinning_ref);
                thread->thread_pinning_ref = NULL;
        }
+
 }
 
 /*
@@ -557,7 +553,7 @@ get_current_thread_ptr_for_domain (MonoDomain *domain, MonoInternalThread *threa
        mono_domain_unlock (domain);
        g_assert (offset);
 
-       return get_thread_static_data (thread, offset);
+       return (MonoThread **)get_thread_static_data (thread, offset);
 }
 
 static void
@@ -595,8 +591,8 @@ create_internal_thread (void)
        vt = mono_class_vtable (mono_get_root_domain (), mono_defaults.internal_thread_class);
        thread = (MonoInternalThread*)mono_gc_alloc_mature (vt);
 
-       thread->synch_cs = g_new0 (mono_mutex_t, 1);
-       mono_mutex_init_recursive (thread->synch_cs);
+       thread->synch_cs = g_new0 (MonoCoopMutex, 1);
+       mono_coop_mutex_init_recursive (thread->synch_cs);
 
        thread->apartment_state = ThreadApartmentState_Unknown;
        thread->managed_id = get_next_managed_thread_id ();
@@ -635,7 +631,7 @@ static guint32 WINAPI start_wrapper_internal(void *data)
        MonoObject *start_delegate = start_info->delegate;
        MonoDomain *domain = start_info->obj->obj.vtable->domain;
 
-       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Start wrapper", __func__, GetCurrentThreadId ()));
+       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Start wrapper", __func__, mono_native_thread_id_get ()));
 
        /* We can be sure start_info->obj->tid and
         * start_info->obj->handle have been set, because the thread
@@ -678,10 +674,12 @@ static guint32 WINAPI start_wrapper_internal(void *data)
         */
        mono_thread_new_init (tid, &tid, start_func);
        internal->stack_ptr = &tid;
+       if (domain != mono_get_root_domain ())
+               set_current_thread_for_domain (domain, internal, start_info->obj);
 
-       LIBGC_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT",%d) Setting thread stack to %p", __func__, GetCurrentThreadId (), getpid (), thread->stack_ptr));
+       LIBGC_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT",%d) Setting thread stack to %p", __func__, mono_native_thread_id_get (), getpid (), thread->stack_ptr));
 
-       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Setting current_object_key to %p", __func__, GetCurrentThreadId (), internal));
+       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Setting current_object_key to %p", __func__, mono_native_thread_id_get (), internal));
 
        /* On 2.0 profile (and higher), set explicitly since state might have been
           Unknown */
@@ -730,7 +728,7 @@ static guint32 WINAPI start_wrapper_internal(void *data)
         * call thread_cleanup() on this thread's behalf.
         */
 
-       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Start wrapper terminating", __func__, GetCurrentThreadId ()));
+       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Start wrapper terminating", __func__, mono_native_thread_id_get ()));
 
        /* Do any cleanup needed for apartment state. This
         * cannot be done in thread_cleanup since thread_cleanup could be 
@@ -817,10 +815,8 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, StartInfo *star
         */
        create_flags = CREATE_SUSPENDED;
 
-       MONO_PREPARE_BLOCKING;
        thread_handle = mono_threads_create_thread ((LPTHREAD_START_ROUTINE)start_wrapper, start_info,
                                                                                                stack_size, create_flags, &tid);
-       MONO_FINISH_BLOCKING;
 
        if (thread_handle == NULL) {
                /* The thread couldn't be created, so throw an exception */
@@ -843,7 +839,7 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, StartInfo *star
        if (threadpool_thread)
                mono_thread_set_state (internal, ThreadState_Background);
 
-       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Launching thread %p (%"G_GSIZE_FORMAT")", __func__, GetCurrentThreadId (), internal, (gsize)internal->tid));
+       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Launching thread %p (%"G_GSIZE_FORMAT")", __func__, mono_native_thread_id_get (), internal, (gsize)internal->tid));
 
        /* Only store the handle when the thread is about to be
         * launched, to avoid the main thread deadlocking while trying
@@ -852,9 +848,7 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, StartInfo *star
        if (!handle_store (thread, FALSE))
                return FALSE;
 
-       MONO_PREPARE_BLOCKING;
        mono_thread_info_resume (tid);
-       MONO_FINISH_BLOCKING;
 
        if (internal->start_notify) {
                /*
@@ -863,7 +857,7 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, StartInfo *star
                 * to look up the data believing the thread has
                 * started
                 */
-               THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") waiting for thread %p (%"G_GSIZE_FORMAT") to start", __func__, GetCurrentThreadId (), internal, (gsize)internal->tid));
+               THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") waiting for thread %p (%"G_GSIZE_FORMAT") to start", __func__, mono_native_thread_id_get (), internal, (gsize)internal->tid));
 
                MONO_PREPARE_BLOCKING;
                WaitForSingleObjectEx (internal->start_notify, INFINITE, FALSE);
@@ -873,7 +867,7 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, StartInfo *star
                internal->start_notify = NULL;
        }
 
-       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Done launching thread %p (%"G_GSIZE_FORMAT")", __func__, GetCurrentThreadId (), internal, (gsize)internal->tid));
+       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Done launching thread %p (%"G_GSIZE_FORMAT")", __func__, mono_native_thread_id_get (), internal, (gsize)internal->tid));
 
        return TRUE;
 }
@@ -913,7 +907,7 @@ mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gb
        MONO_OBJECT_SETREF (thread, internal_thread, internal);
 
        start_info = g_new0 (StartInfo, 1);
-       start_info->func = func;
+       start_info->func = (guint32 (*)(void *))func;
        start_info->obj = thread;
        start_info->start_arg = arg;
 
@@ -922,8 +916,10 @@ mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gb
                return NULL;
 
        /* Check that the managed and unmanaged layout of MonoInternalThread matches */
+#ifndef MONO_CROSS_COMPILE
        if (mono_check_corlib_version () == NULL)
                g_assert (((char*)&internal->unused2 - (char*)internal) == mono_defaults.internal_thread_class->fields [mono_defaults.internal_thread_class->field.count - 1].offset);
+#endif
 
        return internal;
 }
@@ -947,7 +943,7 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
        MonoInternalThread *thread;
        MonoThread *current_thread;
        HANDLE thread_handle;
-       gsize tid;
+       MonoNativeThreadId tid;
 
        if ((thread = mono_thread_internal_current ())) {
                if (domain != mono_domain_get ())
@@ -957,7 +953,7 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
        }
 
        if (!mono_gc_register_thread (&domain)) {
-               g_error ("Thread %"G_GSIZE_FORMAT" calling into managed code is not registered with the GC. On UNIX, this can be fixed by #include-ing <gc.h> before <pthread.h> in the file containing the thread creation code.", GetCurrentThreadId ());
+               g_error ("Thread %"G_GSIZE_FORMAT" calling into managed code is not registered with the GC. On UNIX, this can be fixed by #include-ing <gc.h> before <pthread.h> in the file containing the thread creation code.", mono_native_thread_id_get ());
        }
 
        thread = create_internal_thread ();
@@ -965,10 +961,10 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
        thread_handle = mono_thread_info_open_handle ();
        g_assert (thread_handle);
 
-       tid=GetCurrentThreadId ();
+       tid=mono_native_thread_id_get ();
 
        thread->handle = thread_handle;
-       thread->tid = tid;
+       thread->tid = MONO_NATIVE_THREAD_ID_TO_UINT (tid);
        thread->stack_ptr = &tid;
 
        THREAD_DEBUG (g_message ("%s: Attached thread ID %"G_GSIZE_FORMAT" (handle %p)", __func__, tid, thread_handle));
@@ -983,10 +979,10 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
        if (!handle_store (current_thread, force_attach)) {
                /* Mono is shutting down, so just wait for the end */
                for (;;)
-                       Sleep (10000);
+                       mono_thread_info_sleep (10000, NULL);
        }
 
-       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Setting current_object_key to %p", __func__, GetCurrentThreadId (), thread));
+       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Setting current_object_key to %p", __func__, mono_native_thread_id_get (), thread));
 
        SET_CURRENT_OBJECT (thread);
        mono_domain_set (domain, TRUE);
@@ -1005,13 +1001,13 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
                mono_thread_info_get_stack_bounds (&staddr, &stsize);
 
                if (staddr == NULL)
-                       mono_thread_attach_cb (tid, &tid);
+                       mono_thread_attach_cb (MONO_NATIVE_THREAD_ID_TO_UINT (tid), &tid);
                else
-                       mono_thread_attach_cb (tid, staddr + stsize);
+                       mono_thread_attach_cb (MONO_NATIVE_THREAD_ID_TO_UINT (tid), staddr + stsize);
        }
 
        // FIXME: Need a separate callback
-       mono_profiler_thread_start (tid);
+       mono_profiler_thread_start (MONO_NATIVE_THREAD_ID_TO_UINT (tid));
 
        return current_thread;
 }
@@ -1086,7 +1082,7 @@ ves_icall_System_Threading_Thread_ConstructInternalThread (MonoThread *this_obj)
 
        internal->state = ThreadState_Unstarted;
 
-       InterlockedCompareExchangePointer ((gpointer)&this_obj->internal_thread, internal, NULL);
+       InterlockedCompareExchangePointer ((volatile gpointer *)&this_obj->internal_thread, internal, NULL);
 }
 
 HANDLE
@@ -1154,9 +1150,9 @@ ves_icall_System_Threading_InternalThread_Thread_free_internal (MonoInternalThre
                CloseHandle (thread);
 
        if (this_obj->synch_cs) {
-               mono_mutex_t *synch_cs = this_obj->synch_cs;
+               MonoCoopMutex *synch_cs = this_obj->synch_cs;
                this_obj->synch_cs = NULL;
-               mono_mutex_destroy (synch_cs);
+               mono_coop_mutex_destroy (synch_cs);
                g_free (synch_cs);
        }
 
@@ -1176,17 +1172,17 @@ ves_icall_System_Threading_Thread_Sleep_internal(gint32 ms)
        THREAD_DEBUG (g_message ("%s: Sleeping for %d ms", __func__, ms));
 
        mono_thread_current_check_pending_interrupt ();
-       
+
        while (TRUE) {
+               gboolean alerted = FALSE;
+
                mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
-       
-               MONO_PREPARE_BLOCKING;
-               res = SleepEx(ms,TRUE);
-               MONO_FINISH_BLOCKING;
-       
+
+               res = mono_thread_info_sleep (ms, &alerted);
+
                mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
 
-               if (res == WAIT_IO_COMPLETION) { /* we might have been interrupted */
+               if (alerted) {
                        MonoException* exc = mono_thread_execute_interruption ();
                        if (exc) {
                                mono_raise_exception (exc);
@@ -1305,7 +1301,7 @@ ves_icall_System_Threading_Thread_SetName_internal (MonoInternalThread *this_obj
 }
 
 int
-ves_icall_System_Threading_Thread_GetPriority (MonoThread *this)
+ves_icall_System_Threading_Thread_GetPriority (MonoThread *this_obj)
 {
        return ThreadPriority_Lowest;
 }
@@ -1362,6 +1358,23 @@ mono_thread_current (void)
        return *current_thread_ptr;
 }
 
+/* Return the thread object belonging to INTERNAL in the current domain */
+static MonoThread *
+mono_thread_current_for_thread (MonoInternalThread *internal)
+{
+       MonoDomain *domain = mono_domain_get ();
+       MonoThread **current_thread_ptr;
+
+       g_assert (internal);
+       current_thread_ptr = get_current_thread_ptr_for_domain (domain, internal);
+
+       if (!*current_thread_ptr) {
+               g_assert (domain != mono_get_root_domain ());
+               *current_thread_ptr = new_thread_with_internal (domain, internal);
+       }
+       return *current_thread_ptr;
+}
+
 MonoInternalThread*
 mono_thread_internal_current (void)
 {
@@ -1490,10 +1503,10 @@ gboolean ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_
        g_free(handles);
 
        if(ret==WAIT_FAILED) {
-               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait failed", __func__, GetCurrentThreadId ()));
+               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait failed", __func__, mono_native_thread_id_get ()));
                return(FALSE);
        } else if(ret==WAIT_TIMEOUT) {
-               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait timed out", __func__, GetCurrentThreadId ()));
+               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait timed out", __func__, mono_native_thread_id_get ()));
                return(FALSE);
        }
        
@@ -1532,7 +1545,7 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_ha
 
        mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
 
-       THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") returning %d", __func__, GetCurrentThreadId (), ret));
+       THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") returning %d", __func__, mono_native_thread_id_get (), ret));
 
        /*
         * These need to be here.  See MSDN dos on WaitForMultipleObjects.
@@ -1554,7 +1567,7 @@ gboolean ves_icall_System_Threading_WaitHandle_WaitOne_internal(MonoObject *this
        guint32 ret;
        MonoInternalThread *thread = mono_thread_internal_current ();
 
-       THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") waiting for %p, %d ms", __func__, GetCurrentThreadId (), handle, ms));
+       THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") waiting for %p, %d ms", __func__, mono_native_thread_id_get (), handle, ms));
        
        if(ms== -1) {
                ms=INFINITE;
@@ -1569,10 +1582,10 @@ gboolean ves_icall_System_Threading_WaitHandle_WaitOne_internal(MonoObject *this
        mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
        
        if(ret==WAIT_FAILED) {
-               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait failed", __func__, GetCurrentThreadId ()));
+               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait failed", __func__, mono_native_thread_id_get ()));
                return(FALSE);
        } else if(ret==WAIT_TIMEOUT) {
-               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait timed out", __func__, GetCurrentThreadId ()));
+               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait timed out", __func__, mono_native_thread_id_get ()));
                return(FALSE);
        }
        
@@ -1909,7 +1922,7 @@ MonoObject*
 ves_icall_System_Threading_Interlocked_CompareExchange_T (MonoObject **location, MonoObject *value, MonoObject *comparand)
 {
        MonoObject *res;
-       res = InterlockedCompareExchangePointer ((gpointer *)location, value, comparand);
+       res = (MonoObject *)InterlockedCompareExchangePointer ((volatile gpointer *)location, value, comparand);
        mono_gc_wbarrier_generic_nostore (location);
        return res;
 }
@@ -1918,7 +1931,7 @@ MonoObject*
 ves_icall_System_Threading_Interlocked_Exchange_T (MonoObject **location, MonoObject *value)
 {
        MonoObject *res;
-       res = InterlockedExchangePointer ((gpointer *)location, value);
+       res = (MonoObject *)InterlockedExchangePointer ((volatile gpointer *)location, value);
        mono_gc_wbarrier_generic_nostore (location);
        return res;
 }
@@ -1967,9 +1980,9 @@ ves_icall_System_Threading_Thread_MemoryBarrier (void)
 }
 
 void
-ves_icall_System_Threading_Thread_ClrState (MonoInternalThread* this, guint32 state)
+ves_icall_System_Threading_Thread_ClrState (MonoInternalThread* this_obj, guint32 state)
 {
-       mono_thread_clr_state (thisstate);
+       mono_thread_clr_state (this_obj, (MonoThreadState)state);
 
        if (state & ThreadState_Background) {
                /* If the thread changes the background mode, the main thread has to
@@ -1981,9 +1994,9 @@ ves_icall_System_Threading_Thread_ClrState (MonoInternalThread* this, guint32 st
 }
 
 void
-ves_icall_System_Threading_Thread_SetState (MonoInternalThread* this, guint32 state)
+ves_icall_System_Threading_Thread_SetState (MonoInternalThread* this_obj, guint32 state)
 {
-       mono_thread_set_state (thisstate);
+       mono_thread_set_state (this_obj, (MonoThreadState)state);
        
        if (state & ThreadState_Background) {
                /* If the thread changes the background mode, the main thread has to
@@ -1995,15 +2008,15 @@ ves_icall_System_Threading_Thread_SetState (MonoInternalThread* this, guint32 st
 }
 
 guint32
-ves_icall_System_Threading_Thread_GetState (MonoInternalThread* this)
+ves_icall_System_Threading_Thread_GetState (MonoInternalThread* this_obj)
 {
        guint32 state;
 
-       LOCK_THREAD (this);
+       LOCK_THREAD (this_obj);
        
-       state = this->state;
+       state = this_obj->state;
 
-       UNLOCK_THREAD (this);
+       UNLOCK_THREAD (this_obj);
        
        return state;
 }
@@ -2011,7 +2024,7 @@ ves_icall_System_Threading_Thread_GetState (MonoInternalThread* this)
 void ves_icall_System_Threading_Thread_Interrupt_internal (MonoThread *this_obj)
 {
        MonoInternalThread *current;
-       gboolean throw;
+       gboolean throw_;
        MonoInternalThread *thread = this_obj->internal_thread;
 
        LOCK_THREAD (thread);
@@ -2019,11 +2032,11 @@ void ves_icall_System_Threading_Thread_Interrupt_internal (MonoThread *this_obj)
        current = mono_thread_internal_current ();
 
        thread->thread_interrupt_requested = TRUE;
-       throw = current != thread && (thread->state & ThreadState_WaitSleepJoin);
+       throw_ = current != thread && (thread->state & ThreadState_WaitSleepJoin);
 
        UNLOCK_THREAD (thread);
        
-       if (throw) {
+       if (throw_) {
                abort_thread_internal (thread, TRUE, FALSE);
        }
 }
@@ -2031,18 +2044,18 @@ void ves_icall_System_Threading_Thread_Interrupt_internal (MonoThread *this_obj)
 void mono_thread_current_check_pending_interrupt ()
 {
        MonoInternalThread *thread = mono_thread_internal_current ();
-       gboolean throw = FALSE;
+       gboolean throw_ = FALSE;
 
        LOCK_THREAD (thread);
        
        if (thread->thread_interrupt_requested) {
-               throw = TRUE;
+               throw_ = TRUE;
                thread->thread_interrupt_requested = FALSE;
        }
        
        UNLOCK_THREAD (thread);
 
-       if (throw) {
+       if (throw_) {
                mono_raise_exception (mono_get_exception_thread_interrupted ());
        }
 }
@@ -2077,15 +2090,15 @@ ves_icall_System_Threading_Thread_Abort (MonoInternalThread *thread, MonoObject
        }
        thread->abort_exc = NULL;
 
-       UNLOCK_THREAD (thread);
-
-       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Abort requested for %p (%"G_GSIZE_FORMAT")", __func__, GetCurrentThreadId (), thread, (gsize)thread->tid));
+       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Abort requested for %p (%"G_GSIZE_FORMAT")", __func__, mono_native_thread_id_get (), thread, (gsize)thread->tid));
 
        /* During shutdown, we can't wait for other threads */
        if (!shutting_down)
                /* Make sure the thread is awake */
                mono_thread_resume (thread);
-       
+
+       UNLOCK_THREAD (thread);
+
        abort_thread_internal (thread, TRUE, TRUE);
 }
 
@@ -2202,14 +2215,12 @@ ves_icall_System_Threading_Thread_Suspend (MonoThread *this_obj)
        }
 }
 
+/* LOCKING: LOCK_THREAD(thread) must be held */
 static gboolean
 mono_thread_resume (MonoInternalThread *thread)
 {
-       LOCK_THREAD (thread);
-
        if ((thread->state & ThreadState_SuspendRequested) != 0) {
                thread->state &= ~ThreadState_SuspendRequested;
-               UNLOCK_THREAD (thread);
                return TRUE;
        }
 
@@ -2218,19 +2229,32 @@ mono_thread_resume (MonoInternalThread *thread)
                (thread->state & ThreadState_Aborted) != 0 || 
                (thread->state & ThreadState_Stopped) != 0)
        {
-               UNLOCK_THREAD (thread);
                return FALSE;
        }
 
-       return resume_thread_internal (thread);
+       UNLOCK_THREAD (thread);
+
+       /* Awake the thread */
+       if (!mono_thread_info_resume (thread_get_tid (thread)))
+               return FALSE;
+
+       LOCK_THREAD (thread);
+
+       thread->state &= ~ThreadState_Suspended;
+
+       return TRUE;
 }
 
 void
 ves_icall_System_Threading_Thread_Resume (MonoThread *thread)
 {
-       if (!thread->internal_thread || !mono_thread_resume (thread->internal_thread)) {
+       if (!thread->internal_thread) {
                mono_set_pending_exception (mono_get_exception_thread_state ("Thread has not been started, or is dead."));
-               return;
+       } else {
+               LOCK_THREAD (thread->internal_thread);
+               if (!mono_thread_resume (thread->internal_thread))
+                       mono_set_pending_exception (mono_get_exception_thread_state ("Thread has not been started, or is dead."));
+               UNLOCK_THREAD (thread->internal_thread);
        }
 }
 
@@ -2361,19 +2385,19 @@ ves_icall_System_Threading_Thread_VolatileReadFloat (void *ptr)
 gint8
 ves_icall_System_Threading_Volatile_Read1 (void *ptr)
 {
-       return InterlockedRead8 (ptr);
+       return InterlockedRead8 ((volatile gint8 *)ptr);
 }
 
 gint16
 ves_icall_System_Threading_Volatile_Read2 (void *ptr)
 {
-       return InterlockedRead16 (ptr);
+       return InterlockedRead16 ((volatile gint16 *)ptr);
 }
 
 gint32
 ves_icall_System_Threading_Volatile_Read4 (void *ptr)
 {
-       return InterlockedRead (ptr);
+       return InterlockedRead ((volatile gint32 *)ptr);
 }
 
 gint64
@@ -2388,13 +2412,13 @@ ves_icall_System_Threading_Volatile_Read8 (void *ptr)
                return val;
        }
 #endif
-       return InterlockedRead64 (ptr);
+       return InterlockedRead64 ((volatile gint64 *)ptr);
 }
 
 void *
 ves_icall_System_Threading_Volatile_ReadIntPtr (void *ptr)
 {
-       return InterlockedReadPointer (ptr);
+       return InterlockedReadPointer ((volatile gpointer *)ptr);
 }
 
 double
@@ -2412,7 +2436,7 @@ ves_icall_System_Threading_Volatile_ReadDouble (void *ptr)
        }
 #endif
 
-       u.ival = InterlockedRead64 (ptr);
+       u.ival = InterlockedRead64 ((volatile gint64 *)ptr);
 
        return u.fval;
 }
@@ -2422,7 +2446,7 @@ ves_icall_System_Threading_Volatile_ReadFloat (void *ptr)
 {
        IntFloatUnion u;
 
-       u.ival = InterlockedRead (ptr);
+       u.ival = InterlockedRead ((volatile gint32 *)ptr);
 
        return u.fval;
 }
@@ -2430,7 +2454,7 @@ ves_icall_System_Threading_Volatile_ReadFloat (void *ptr)
 MonoObject*
 ves_icall_System_Threading_Volatile_Read_T (void *ptr)
 {
-       return InterlockedReadPointer (ptr);
+       return (MonoObject *)InterlockedReadPointer ((volatile gpointer *)ptr);
 }
 
 void
@@ -2484,19 +2508,19 @@ ves_icall_System_Threading_Thread_VolatileWriteFloat (void *ptr, float value)
 void
 ves_icall_System_Threading_Volatile_Write1 (void *ptr, gint8 value)
 {
-       InterlockedWrite8 (ptr, value);
+       InterlockedWrite8 ((volatile gint8 *)ptr, value);
 }
 
 void
 ves_icall_System_Threading_Volatile_Write2 (void *ptr, gint16 value)
 {
-       InterlockedWrite16 (ptr, value);
+       InterlockedWrite16 ((volatile gint16 *)ptr, value);
 }
 
 void
 ves_icall_System_Threading_Volatile_Write4 (void *ptr, gint32 value)
 {
-       InterlockedWrite (ptr, value);
+       InterlockedWrite ((volatile gint32 *)ptr, value);
 }
 
 void
@@ -2511,13 +2535,13 @@ ves_icall_System_Threading_Volatile_Write8 (void *ptr, gint64 value)
        }
 #endif
 
-       InterlockedWrite64 (ptr, value);
+       InterlockedWrite64 ((volatile gint64 *)ptr, value);
 }
 
 void
 ves_icall_System_Threading_Volatile_WriteIntPtr (void *ptr, void *value)
 {
-       InterlockedWritePointer (ptr, value);
+       InterlockedWritePointer ((volatile gpointer *)ptr, value);
 }
 
 void
@@ -2536,7 +2560,7 @@ ves_icall_System_Threading_Volatile_WriteDouble (void *ptr, double value)
 
        u.fval = value;
 
-       InterlockedWrite64 (ptr, u.ival);
+       InterlockedWrite64 ((volatile gint64 *)ptr, u.ival);
 }
 
 void
@@ -2546,7 +2570,7 @@ ves_icall_System_Threading_Volatile_WriteFloat (void *ptr, float value)
 
        u.fval = value;
 
-       InterlockedWrite (ptr, u.ival);
+       InterlockedWrite ((volatile gint32 *)ptr, u.ival);
 }
 
 void
@@ -2637,9 +2661,10 @@ mono_thread_init_tls (void)
 void mono_thread_init (MonoThreadStartCB start_cb,
                       MonoThreadAttachCB attach_cb)
 {
-       mono_mutex_init_recursive(&threads_mutex);
-       mono_mutex_init_recursive(&interlocked_mutex);
-       mono_mutex_init_recursive(&joinable_threads_mutex);
+       mono_coop_mutex_init_recursive (&threads_mutex);
+
+       mono_os_mutex_init_recursive(&interlocked_mutex);
+       mono_os_mutex_init_recursive(&joinable_threads_mutex);
        
        background_change_event = CreateEvent (NULL, TRUE, FALSE, NULL);
        g_assert(background_change_event != NULL);
@@ -2680,10 +2705,10 @@ void mono_thread_cleanup (void)
         * critical sections can be locked when mono_thread_cleanup is
         * called.
         */
-       mono_mutex_destroy (&threads_mutex);
-       mono_mutex_destroy (&interlocked_mutex);
-       mono_mutex_destroy (&delayed_free_table_mutex);
-       mono_mutex_destroy (&small_id_mutex);
+       mono_coop_mutex_destroy (&threads_mutex);
+       mono_os_mutex_destroy (&interlocked_mutex);
+       mono_os_mutex_destroy (&delayed_free_table_mutex);
+       mono_os_mutex_destroy (&small_id_mutex);
        CloseHandle (background_change_event);
 #endif
 
@@ -2888,17 +2913,18 @@ static gboolean
 remove_and_abort_threads (gpointer key, gpointer value, gpointer user)
 {
        struct wait_data *wait=(struct wait_data *)user;
-       gsize self = GetCurrentThreadId ();
-       MonoInternalThread *thread = value;
+       MonoNativeThreadId self = mono_native_thread_id_get ();
+       MonoInternalThread *thread = (MonoInternalThread *)value;
        HANDLE handle;
 
        if (wait->num >= MAXIMUM_WAIT_OBJECTS)
                return FALSE;
 
        /* The finalizer thread is not a background thread */
-       if (thread->tid != self && (thread->state & ThreadState_Background) != 0 &&
-               !(thread->flags & MONO_THREAD_FLAG_DONT_MANAGE)) {
-       
+       if (!mono_native_thread_id_equals (thread_get_tid (thread), self)
+            && (thread->state & ThreadState_Background) != 0
+            && (thread->flags & MONO_THREAD_FLAG_DONT_MANAGE) == 0
+       ) {
                handle = mono_threads_open_thread_handle (thread->handle, thread_get_tid (thread));
                if (handle == NULL)
                        return FALSE;
@@ -2913,7 +2939,8 @@ remove_and_abort_threads (gpointer key, gpointer value, gpointer user)
                return TRUE;
        }
 
-       return (thread->tid != self && !mono_gc_is_finalizer_internal_thread (thread)); 
+       return !mono_native_thread_id_equals (thread_get_tid (thread), self)
+               && !mono_gc_is_finalizer_internal_thread (thread);
 }
 
 /** 
@@ -3041,29 +3068,6 @@ void mono_thread_manage (void)
        mono_thread_info_yield ();
 }
 
-static void terminate_thread (gpointer key, gpointer value, gpointer user)
-{
-       MonoInternalThread *thread=(MonoInternalThread *)value;
-       
-       if(thread->tid != (gsize)user) {
-               /*TerminateThread (thread->handle, -1);*/
-       }
-}
-
-void mono_thread_abort_all_other_threads (void)
-{
-       gsize self = GetCurrentThreadId ();
-
-       mono_threads_lock ();
-       THREAD_DEBUG (g_message ("%s: There are %d threads to abort", __func__,
-                                mono_g_hash_table_size (threads));
-                     mono_g_hash_table_foreach (threads, print_tids, NULL));
-
-       mono_g_hash_table_foreach (threads, terminate_thread, (gpointer)self);
-       
-       mono_threads_unlock ();
-}
-
 static void
 collect_threads_for_suspend (gpointer key, gpointer value, gpointer user_data)
 {
@@ -3102,7 +3106,7 @@ void mono_thread_suspend_all_other_threads (void)
        struct wait_data wait_data;
        struct wait_data *wait = &wait_data;
        int i;
-       gsize self = GetCurrentThreadId ();
+       MonoNativeThreadId self = mono_native_thread_id_get ();
        guint32 eventidx = 0;
        gboolean starting, finished;
 
@@ -3144,7 +3148,10 @@ void mono_thread_suspend_all_other_threads (void)
                for (i = 0; i < wait->num; ++i) {
                        MonoInternalThread *thread = wait->threads [i];
 
-                       if ((thread->tid == self) || mono_gc_is_finalizer_internal_thread (thread) || (thread->flags & MONO_THREAD_FLAG_DONT_MANAGE)) {
+                       if (mono_native_thread_id_equals (thread_get_tid (thread), self)
+                            || mono_gc_is_finalizer_internal_thread (thread)
+                            || (thread->flags & MONO_THREAD_FLAG_DONT_MANAGE)
+                       ) {
                                //CloseHandle (wait->handles [i]);
                                wait->threads [i] = NULL; /* ignore this thread in next loop */
                                continue;
@@ -3189,62 +3196,145 @@ void mono_thread_suspend_all_other_threads (void)
                                starting = FALSE;
                        mono_threads_unlock ();
                        if (starting)
-                               Sleep (100);
+                               mono_thread_info_sleep (100, NULL);
                        else
                                finished = TRUE;
                }
        }
 }
 
+typedef struct {
+       MonoInternalThread *thread;
+       MonoStackFrameInfo *frames;
+       int nframes, max_frames;
+       int nthreads, max_threads;
+       MonoInternalThread **threads;
+} ThreadDumpUserData;
+
 static gboolean thread_dump_requested;
 
-static G_GNUC_UNUSED gboolean
-print_stack_frame_to_string (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer data)
+/* This needs to be async safe */
+static gboolean
+collect_frame (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer data)
 {
-       GString *p = (GString*)data;
-       MonoMethod *method = NULL;
-       if (frame->type == FRAME_TYPE_MANAGED)
-               method = mono_jit_info_get_method (frame->ji);
+       ThreadDumpUserData *ud = (ThreadDumpUserData *)data;
 
-       if (method) {
-               gchar *location = mono_debug_print_stack_frame (method, frame->native_offset, frame->domain);
-               g_string_append_printf (p, "  %s\n", location);
-               g_free (location);
-       } else
-               g_string_append_printf (p, "  at <unknown> <0x%05x>\n", frame->native_offset);
+       if (ud->nframes < ud->max_frames) {
+               memcpy (&ud->frames [ud->nframes], frame, sizeof (MonoStackFrameInfo));
+               ud->nframes ++;
+       }
 
        return FALSE;
 }
 
+/* This needs to be async safe */
 static SuspendThreadResult
-print_thread_dump (MonoThreadInfo *info, gpointer ud)
+get_thread_dump (MonoThreadInfo *info, gpointer ud)
+{
+       ThreadDumpUserData *user_data = (ThreadDumpUserData *)ud;
+       MonoInternalThread *thread = user_data->thread;
+
+#if 0
+/* This no longer works with remote unwinding */
+#ifndef HOST_WIN32
+       wapi_desc = wapi_current_thread_desc ();
+       g_string_append_printf (text, " tid=0x%p this=0x%p %s\n", (gpointer)(gsize)thread->tid, thread,  wapi_desc);
+       free (wapi_desc);
+#endif
+#endif
+
+       if (thread == mono_thread_internal_current ())
+               mono_get_eh_callbacks ()->mono_walk_stack_with_ctx (collect_frame, NULL, MONO_UNWIND_SIGNAL_SAFE, ud);
+       else
+               mono_get_eh_callbacks ()->mono_walk_stack_with_state (collect_frame, mono_thread_info_get_suspend_state (info), MONO_UNWIND_SIGNAL_SAFE, ud);
+
+       return MonoResumeThread;
+}
+
+typedef struct {
+       int nthreads, max_threads;
+       MonoInternalThread **threads;
+} CollectThreadsUserData;
+
+static void
+collect_thread (gpointer key, gpointer value, gpointer user)
+{
+       CollectThreadsUserData *ud = (CollectThreadsUserData *)user;
+       MonoInternalThread *thread = (MonoInternalThread *)value;
+
+       if (ud->nthreads < ud->max_threads)
+               ud->threads [ud->nthreads ++] = thread;
+}
+
+/*
+ * Collect running threads into the THREADS array.
+ * THREADS should be an array allocated on the stack.
+ */
+static int
+collect_threads (MonoInternalThread **thread_array, int max_threads)
+{
+       CollectThreadsUserData ud;
+
+       memset (&ud, 0, sizeof (ud));
+       /* This array contains refs, but its on the stack, so its ok */
+       ud.threads = thread_array;
+       ud.max_threads = max_threads;
+
+       mono_threads_lock ();
+       mono_g_hash_table_foreach (threads, collect_thread, &ud);
+       mono_threads_unlock ();
+
+       return ud.nthreads;
+}
+
+static void
+dump_thread (MonoInternalThread *thread, ThreadDumpUserData *ud)
 {
-       MonoInternalThread *thread = ud;
        GString* text = g_string_new (0);
        char *name;
        GError *error = NULL;
+       int i;
+
+       ud->thread = thread;
+       ud->nframes = 0;
 
+       /* Collect frames for the thread */
+       if (thread == mono_thread_internal_current ()) {
+               get_thread_dump (mono_thread_info_current (), ud);
+       } else {
+               mono_thread_info_safe_suspend_and_run (thread_get_tid (thread), FALSE, get_thread_dump, ud);
+       }
+
+       /*
+        * Do all the non async-safe work outside of get_thread_dump.
+        */
        if (thread->name) {
                name = g_utf16_to_utf8 (thread->name, thread->name_len, NULL, NULL, &error);
                g_assert (!error);
                g_string_append_printf (text, "\n\"%s\"", name);
                g_free (name);
        }
-       else if (thread->threadpool_thread)
+       else if (thread->threadpool_thread) {
                g_string_append (text, "\n\"<threadpool thread>\"");
-       else
+       } else {
                g_string_append (text, "\n\"<unnamed thread>\"");
+       }
 
-#if 0
-/* This no longer works with remote unwinding */
-#ifndef HOST_WIN32
-       wapi_desc = wapi_current_thread_desc ();
-       g_string_append_printf (text, " tid=0x%p this=0x%p %s\n", (gpointer)(gsize)thread->tid, thread,  wapi_desc);
-       free (wapi_desc);
-#endif
-#endif
+       for (i = 0; i < ud->nframes; ++i) {
+               MonoStackFrameInfo *frame = &ud->frames [i];
+               MonoMethod *method = NULL;
 
-       mono_get_eh_callbacks ()->mono_walk_stack_with_state (print_stack_frame_to_string, mono_thread_info_get_suspend_state (info), MONO_UNWIND_SIGNAL_SAFE, text);
+               if (frame->type == FRAME_TYPE_MANAGED)
+                       method = mono_jit_info_get_method (frame->ji);
+
+               if (method) {
+                       gchar *location = mono_debug_print_stack_frame (method, frame->native_offset, frame->domain);
+                       g_string_append_printf (text, "  %s\n", location);
+                       g_free (location);
+               } else {
+                       g_string_append_printf (text, "  at <unknown> <0x%05x>\n", frame->native_offset);
+               }
+       }
 
        fprintf (stdout, "%s", text->str);
 
@@ -3254,51 +3344,114 @@ print_thread_dump (MonoThreadInfo *info, gpointer ud)
 
        g_string_free (text, TRUE);
        fflush (stdout);
-       return MonoResumeThread;
-}
-
-static void
-dump_thread (gpointer key, gpointer value, gpointer user)
-{
-       MonoInternalThread *thread = (MonoInternalThread *)value;
-
-       if (thread == mono_thread_internal_current ())
-               return;
-
-       /*
-       FIXME This still can hang if we stop a thread during malloc.
-       FIXME This can hang if we suspend on a critical method and the GC kicks in. A fix might be to have function
-       that takes a callback and runs it with the target suspended.
-       We probably should loop a bit around trying to get it to either managed code
-       or WSJ state.
-       */
-       mono_thread_info_safe_suspend_and_run (thread_get_tid (thread), FALSE, print_thread_dump, thread);
 }
 
 void
 mono_threads_perform_thread_dump (void)
 {
+       ThreadDumpUserData ud;
+       MonoInternalThread *thread_array [128];
+       int tindex, nthreads;
+
        if (!thread_dump_requested)
                return;
 
        printf ("Full thread dump:\n");
 
-       /* We take the loader lock and the root domain lock as to increase our odds of not deadlocking if
-       something needs then in the process.
-       */
-       mono_loader_lock ();
-       mono_domain_lock (mono_get_root_domain ());
+       /* Make a copy of the threads hash to avoid doing work inside threads_lock () */
+       nthreads = collect_threads (thread_array, 128);
 
-       mono_threads_lock ();
-       mono_g_hash_table_foreach (threads, dump_thread, NULL);
-       mono_threads_unlock ();
+       memset (&ud, 0, sizeof (ud));
+       ud.frames = g_new0 (MonoStackFrameInfo, 256);
+       ud.max_frames = 256;
+
+       for (tindex = 0; tindex < nthreads; ++tindex)
+               dump_thread (thread_array [tindex], &ud);
 
-       mono_domain_unlock (mono_get_root_domain ());
-       mono_loader_unlock ();
+       g_free (ud.frames);
 
        thread_dump_requested = FALSE;
 }
 
+/* Obtain the thread dump of all threads */
+static void
+mono_threads_get_thread_dump (MonoArray **out_threads, MonoArray **out_stack_frames)
+{
+       ThreadDumpUserData ud;
+       MonoInternalThread *thread_array [128];
+       MonoDomain *domain = mono_domain_get ();
+       MonoDebugSourceLocation *location;
+       int tindex, nthreads;
+
+       *out_threads = NULL;
+       *out_stack_frames = NULL;
+
+       /* Make a copy of the threads hash to avoid doing work inside threads_lock () */
+       nthreads = collect_threads (thread_array, 128);
+
+       memset (&ud, 0, sizeof (ud));
+       ud.frames = g_new0 (MonoStackFrameInfo, 256);
+       ud.max_frames = 256;
+
+       *out_threads = mono_array_new (domain, mono_defaults.thread_class, nthreads);
+       *out_stack_frames = mono_array_new (domain, mono_defaults.array_class, nthreads);
+
+       for (tindex = 0; tindex < nthreads; ++tindex) {
+               MonoInternalThread *thread = thread_array [tindex];
+               MonoArray *thread_frames;
+               int i;
+
+               ud.thread = thread;
+               ud.nframes = 0;
+
+               /* Collect frames for the thread */
+               if (thread == mono_thread_internal_current ()) {
+                       get_thread_dump (mono_thread_info_current (), &ud);
+               } else {
+                       mono_thread_info_safe_suspend_and_run (thread_get_tid (thread), FALSE, get_thread_dump, &ud);
+               }
+
+               mono_array_setref_fast (*out_threads, tindex, mono_thread_current_for_thread (thread));
+
+               thread_frames = mono_array_new (domain, mono_defaults.stack_frame_class, ud.nframes);
+               mono_array_setref_fast (*out_stack_frames, tindex, thread_frames);
+
+               for (i = 0; i < ud.nframes; ++i) {
+                       MonoStackFrameInfo *frame = &ud.frames [i];
+                       MonoMethod *method = NULL;
+                       MonoStackFrame *sf = (MonoStackFrame *)mono_object_new (domain, mono_defaults.stack_frame_class);
+
+                       sf->native_offset = frame->native_offset;
+
+                       if (frame->type == FRAME_TYPE_MANAGED)
+                               method = mono_jit_info_get_method (frame->ji);
+
+                       if (method) {
+                               sf->method_address = (gsize) frame->ji->code_start;
+
+                               MONO_OBJECT_SETREF (sf, method, mono_method_get_object (domain, method, NULL));
+
+                               location = mono_debug_lookup_source_location (method, frame->native_offset, domain);
+                               if (location) {
+                                       sf->il_offset = location->il_offset;
+
+                                       if (location && location->source_file) {
+                                               MONO_OBJECT_SETREF (sf, filename, mono_string_new (domain, location->source_file));
+                                               sf->line = location->row;
+                                               sf->column = location->column;
+                                       }
+                                       mono_debug_free_source_location (location);
+                               } else {
+                                       sf->il_offset = -1;
+                               }
+                       }
+                       mono_array_setref (thread_frames, i, sf);
+               }
+       }
+
+       g_free (ud.frames);
+}
+
 /**
  * mono_threads_request_thread_dump:
  *
@@ -3335,7 +3488,7 @@ ref_stack_new (gint initial_size)
 static void
 ref_stack_destroy (gpointer ptr)
 {
-       RefStack *rs = ptr;
+       RefStack *rs = (RefStack *)ptr;
 
        if (rs != NULL) {
                g_free (rs->refs);
@@ -3349,7 +3502,7 @@ ref_stack_push (RefStack *rs, gpointer ptr)
        g_assert (rs != NULL);
 
        if (rs->bottom >= rs->allocated) {
-               rs->refs = g_realloc (rs->refs, rs->allocated * 2 * sizeof (gpointer) + 1);
+               rs->refs = (void **)g_realloc (rs->refs, rs->allocated * 2 * sizeof (gpointer) + 1);
                rs->allocated <<= 1;
                rs->refs [rs->allocated] = NULL;
        }
@@ -3398,7 +3551,7 @@ mono_thread_push_appdomain_ref (MonoDomain *domain)
                SPIN_LOCK (thread->lock_thread_id);
                if (thread->appdomain_refs == NULL)
                        thread->appdomain_refs = ref_stack_new (16);
-               ref_stack_push (thread->appdomain_refs, domain);
+               ref_stack_push ((RefStack *)thread->appdomain_refs, domain);
                SPIN_UNLOCK (thread->lock_thread_id);
        }
 }
@@ -3411,7 +3564,7 @@ mono_thread_pop_appdomain_ref (void)
        if (thread) {
                /* printf ("POP REF: %"G_GSIZE_FORMAT" -> %s.\n", (gsize)thread->tid, ((MonoDomain*)(thread->appdomain_refs->data))->friendly_name); */
                SPIN_LOCK (thread->lock_thread_id);
-               ref_stack_pop (thread->appdomain_refs);
+               ref_stack_pop ((RefStack *)thread->appdomain_refs);
                SPIN_UNLOCK (thread->lock_thread_id);
        }
 }
@@ -3421,7 +3574,7 @@ mono_thread_internal_has_appdomain_ref (MonoInternalThread *thread, MonoDomain *
 {
        gboolean res;
        SPIN_LOCK (thread->lock_thread_id);
-       res = ref_stack_find (thread->appdomain_refs, domain);
+       res = ref_stack_find ((RefStack *)thread->appdomain_refs, domain);
        SPIN_UNLOCK (thread->lock_thread_id);
        return res;
 }
@@ -3592,10 +3745,10 @@ static MonoBitSet *context_reference_bitmaps [NUM_STATIC_DATA_IDX];
 static void
 mark_slots (void *addr, MonoBitSet **bitmaps, MonoGCMarkFunc mark_func, void *gc_data)
 {
-       gpointer *static_data = addr;
+       gpointer *static_data = (gpointer *)addr;
 
        for (int i = 0; i < NUM_STATIC_DATA_IDX; ++i) {
-               void **ptr = static_data [i];
+               void **ptr = (void **)static_data [i];
 
                if (!ptr)
                        continue;
@@ -3645,7 +3798,7 @@ mono_alloc_static_data (gpointer **static_data_ptr, guint32 offset, gboolean thr
                                ctx_desc = mono_gc_make_root_descr_user (mark_ctx_slots);
                }
 
-               static_data = mono_gc_alloc_fixed (static_data_size [0], threadlocal ? tls_desc : ctx_desc,
+               static_data = (void **)mono_gc_alloc_fixed (static_data_size [0], threadlocal ? tls_desc : ctx_desc,
                        threadlocal ? MONO_ROOT_SOURCE_THREAD_STATIC : MONO_ROOT_SOURCE_CONTEXT_STATIC,
                        threadlocal ? "managed thread-static variables" : "managed context-static variables");
                *static_data_ptr = static_data;
@@ -3766,7 +3919,7 @@ context_adjust_static_data (MonoAppContext *ctx)
 static void 
 alloc_thread_static_data_helper (gpointer key, gpointer value, gpointer user)
 {
-       MonoInternalThread *thread = value;
+       MonoInternalThread *thread = (MonoInternalThread *)value;
        guint32 offset = GPOINTER_TO_UINT (user);
 
        mono_alloc_static_data (&(thread->static_data), offset, TRUE);
@@ -3916,8 +4069,8 @@ typedef struct {
 static void 
 free_thread_static_data_helper (gpointer key, gpointer value, gpointer user)
 {
-       MonoInternalThread *thread = value;
-       OffsetSize *data = user;
+       MonoInternalThread *thread = (MonoInternalThread *)value;
+       OffsetSize *data = (OffsetSize *)user;
        int idx = ACCESS_SPECIAL_STATIC_OFFSET (data->offset, index);
        int off = ACCESS_SPECIAL_STATIC_OFFSET (data->offset, offset);
        char *ptr;
@@ -3939,7 +4092,7 @@ free_context_static_data_helper (gpointer key, gpointer value, gpointer user)
        if (!ctx)
                return;
 
-       OffsetSize *data = user;
+       OffsetSize *data = (OffsetSize *)user;
        int idx = ACCESS_SPECIAL_STATIC_OFFSET (data->offset, index);
        int off = ACCESS_SPECIAL_STATIC_OFFSET (data->offset, offset);
        char *ptr;
@@ -3994,7 +4147,7 @@ do_free_special_slot (guint32 offset, guint32 size)
 static void
 do_free_special (gpointer key, gpointer value, gpointer data)
 {
-       MonoClassField *field = key;
+       MonoClassField *field = (MonoClassField *)key;
        guint32 offset = GPOINTER_TO_UINT (value);
        gint32 align;
        guint32 size;
@@ -4403,7 +4556,7 @@ mono_jit_info_match (MonoJitInfo *ji, gpointer ip)
 static gboolean
 last_managed (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer data)
 {
-       MonoJitInfo **dest = data;
+       MonoJitInfo **dest = (MonoJitInfo **)data;
        *dest = frame->ji;
        return TRUE;
 }
@@ -4427,7 +4580,7 @@ typedef struct {
 static SuspendThreadResult
 abort_thread_critical (MonoThreadInfo *info, gpointer ud)
 {
-       AbortThreadData *data = ud;
+       AbortThreadData *data = (AbortThreadData *)ud;
        MonoInternalThread *thread = data->thread;
        MonoJitInfo *ji = NULL;
        gboolean protected_wrapper;
@@ -4507,7 +4660,7 @@ typedef struct{
 static SuspendThreadResult
 suspend_thread_critical (MonoThreadInfo *info, gpointer ud)
 {
-       SuspendThreadData *data = ud;
+       SuspendThreadData *data = (SuspendThreadData *)ud;
        MonoInternalThread *thread = data->thread;
        MonoJitInfo *ji = NULL;
        gboolean protected_wrapper;
@@ -4525,7 +4678,7 @@ suspend_thread_critical (MonoThreadInfo *info, gpointer ud)
                if (InterlockedCompareExchange (&thread->interruption_requested, 1, 0) == 0)
                        InterlockedIncrement (&thread_interruption_requested);
                if (data->interrupt)
-                       data->interrupt_token = mono_thread_info_prepare_interrupt (thread->thread_info);
+                       data->interrupt_token = mono_thread_info_prepare_interrupt ((MonoThreadInfo *)thread->thread_info);
                
                if (mono_thread_notify_pending_exc_fn && !running_managed)
                        /* The JIT will notify the thread about the interruption */
@@ -4568,20 +4721,6 @@ self_suspend_internal (MonoInternalThread *thread)
        mono_thread_info_end_self_suspend ();
 }
 
-/*This is called with @thread synch_cs held and it must release it*/
-static gboolean
-resume_thread_internal (MonoInternalThread *thread)
-{
-       UNLOCK_THREAD (thread);
-       /* Awake the thread */
-       if (!mono_thread_info_resume (thread_get_tid (thread)))
-               return FALSE;
-       LOCK_THREAD (thread);
-       thread->state &= ~ThreadState_Suspended;
-       UNLOCK_THREAD (thread);
-       return TRUE;
-}
-
 
 /*
  * mono_thread_is_foreign:
@@ -4595,7 +4734,7 @@ resume_thread_internal (MonoInternalThread *thread)
 mono_bool
 mono_thread_is_foreign (MonoThread *thread)
 {
-       MonoThreadInfo *info = thread->internal_thread->thread_info;
+       MonoThreadInfo *info = (MonoThreadInfo *)thread->internal_thread->thread_info;
        return info->runtime_thread == FALSE;
 }
 
@@ -4736,3 +4875,9 @@ mono_thread_internal_unhandled_exception (MonoObject* exc)
                }
        }
 }
+
+void
+ves_icall_System_Threading_Thread_GetStackTraces (MonoArray **out_threads, MonoArray **out_stack_traces)
+{
+       mono_threads_get_thread_dump (out_threads, out_stack_traces);
+}