*
* Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
* Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+ * Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
*/
#include <config.h>
#include <mono/utils/mono-time.h>
#include <mono/utils/mono-threads.h>
#include <mono/utils/hazard-pointer.h>
+#include <mono/utils/mono-tls.h>
#include <mono/metadata/gc-internal.h>
static MonoGHashTable *thread_start_args = NULL;
/* The TLS key that holds the MonoObject assigned to each thread */
-static guint32 current_object_key = -1;
+static MonoNativeTlsKey current_object_key;
#ifdef MONO_HAVE_FAST_TLS
/* we need to use both the Tls* functions and __thread because
MONO_FAST_TLS_DECLARE(tls_current_object);
#define SET_CURRENT_OBJECT(x) do { \
MONO_FAST_TLS_SET (tls_current_object, x); \
- TlsSetValue (current_object_key, x); \
+ mono_native_tls_set_value (current_object_key, x); \
} while (FALSE)
#define GET_CURRENT_OBJECT() ((MonoInternalThread*) MONO_FAST_TLS_GET (tls_current_object))
#else
-#define SET_CURRENT_OBJECT(x) TlsSetValue (current_object_key, x)
-#define GET_CURRENT_OBJECT() (MonoInternalThread*) TlsGetValue (current_object_key)
+#define SET_CURRENT_OBJECT(x) mono_native_tls_set_value (current_object_key, x)
+#define GET_CURRENT_OBJECT() (MonoInternalThread*) mono_native_tls_get_value (current_object_key)
#endif
/* function called at thread start */
return InterlockedIncrement (&managed_thread_id_counter);
}
-guint32
+MonoNativeTlsKey
mono_thread_get_tls_key (void)
{
return current_object_key;
}
mono_release_type_locks (thread);
+ ensure_synch_cs_set (thread);
+
EnterCriticalSection (thread->synch_cs);
thread->state |= ThreadState_Stopped;
#if defined(HAVE_PTHREAD_GET_STACKSIZE_NP) && defined(HAVE_PTHREAD_GET_STACKADDR_NP)
*staddr = (guint8*)pthread_get_stackaddr_np (pthread_self ());
*stsize = pthread_get_stacksize_np (pthread_self ());
+
+ /* staddr points to the start of the stack, not the end */
+ *staddr -= *stsize;
*staddr = (guint8*)((gssize)*staddr & ~(mono_pagesize () - 1));
return;
/* FIXME: simplify the mess below */
return arr;
copy = mono_array_new (domain, mono_defaults.byte_class, arr->max_length);
- memcpy (mono_array_addr (copy, guint8, 0), mono_array_addr (arr, guint8, 0), arr->max_length);
+ mono_gc_memmove (mono_array_addr (copy, guint8, 0), mono_array_addr (arr, guint8, 0), arr->max_length);
return copy;
}
void ves_icall_System_Threading_Thread_Interrupt_internal (MonoInternalThread *this)
{
- gboolean throw = FALSE;
-
+ MonoInternalThread *current;
+ gboolean throw;
+
ensure_synch_cs_set (this);
- if (this == mono_thread_internal_current ())
- return;
-
- EnterCriticalSection (this->synch_cs);
-
- this->thread_interrupt_requested = TRUE;
-
- if (this->state & ThreadState_WaitSleepJoin) {
- throw = TRUE;
- }
-
+ current = mono_thread_internal_current ();
+
+ EnterCriticalSection (this->synch_cs);
+
+ this->thread_interrupt_requested = TRUE;
+ throw = current != this && (this->state & ThreadState_WaitSleepJoin);
+
LeaveCriticalSection (this->synch_cs);
if (throw) {
mono_init_static_data_info (&context_static_info);
MONO_FAST_TLS_INIT (tls_current_object);
- current_object_key=TlsAlloc();
+ mono_native_tls_alloc (¤t_object_key, NULL);
THREAD_DEBUG (g_message ("%s: Allocated current_object_key %d", __func__, current_object_key));
mono_thread_start_cb = start_cb;
CloseHandle (background_change_event);
#endif
- TlsFree (current_object_key);
+ mono_native_tls_free (current_object_key);
}
void
print_thread_dump (MonoInternalThread *thread, MonoThreadInfo *info)
{
GString* text = g_string_new (0);
- char *name, *wapi_desc;
+ char *name;
GError *error = NULL;
if (thread->name) {
We probably should loop a bit around trying to get it to either managed code
or WSJ state.
*/
- info = mono_thread_info_safe_suspend_sync ((pthread_t)(gpointer)(gsize)thread->tid, FALSE);
+ info = mono_thread_info_safe_suspend_sync ((MonoNativeThreadId)(gpointer)(gsize)thread->tid, FALSE);
if (!info)
return;
if (!thread->static_data || !thread->static_data [idx])
return;
ptr = ((char*) thread->static_data [idx]) + (data->offset & 0xffffff);
- memset (ptr, 0, data->size);
+ mono_gc_bzero (ptr, data->size);
}
static void
{
MonoJitInfo *ji;
MonoThreadInfo *info = NULL;
+ gboolean protected_wrapper;
+ gboolean running_managed;
if (!mono_thread_info_new_interrupt_enabled ()) {
signal_thread_state_change (thread);
MonoException *exc = mono_thread_request_interruption (can_raise_exception);
if (exc)
mono_raise_exception (exc);
+#ifndef HOST_WIN32
wapi_interrupt_thread (thread->handle);
+#endif
return;
}
}
ji = mono_thread_info_get_last_managed (info);
- gboolean protected_wrapper = ji && mono_threads_is_critical_method (ji->method);
- gboolean running_managed = mono_jit_info_match (ji, MONO_CONTEXT_GET_IP (&info->suspend_state.ctx));
+ protected_wrapper = ji && mono_threads_is_critical_method (ji->method);
+ running_managed = mono_jit_info_match (ji, MONO_CONTEXT_GET_IP (&info->suspend_state.ctx));
if (!protected_wrapper && running_managed) {
/*We are in managed code*/
*/
InterlockedIncrement (&thread_interruption_requested);
mono_thread_info_resume (mono_thread_info_get_tid (info));
+#ifndef HOST_WIN32
wapi_interrupt_thread (thread->handle);
+#endif
}
/*FIXME we need to wait for interruption to complete -- figure out how much into interruption we should wait for here*/
}
if ((thread->state & ThreadState_SuspendRequested) == 0) {
g_assert (0); /*FIXME we should not reach this */
/*Make sure we balance the suspend count.*/
- mono_thread_info_resume ((pthread_t)(gpointer)(gsize)thread->tid);
+ mono_thread_info_resume ((MonoNativeThreadId)(gpointer)(gsize)thread->tid);
} else {
thread->state &= ~ThreadState_SuspendRequested;
thread->state |= ThreadState_Suspended;
} else {
if (InterlockedCompareExchange (&thread->interruption_requested, 1, 0) == 0)
InterlockedIncrement (&thread_interruption_requested);
+#ifndef HOST_WIN32
if (interrupt)
wapi_interrupt_thread (thread->handle);
+#endif
mono_thread_info_resume (mono_thread_info_get_tid (info));
LeaveCriticalSection (thread->synch_cs);
}
LeaveCriticalSection (thread->synch_cs);
/* Awake the thread */
- if (!mono_thread_info_resume ((pthread_t)(gpointer)(gsize)thread->tid))
+ if (!mono_thread_info_resume ((MonoNativeThreadId)(gpointer)(gsize)thread->tid))
return FALSE;
EnterCriticalSection (thread->synch_cs);
thread->state &= ~ThreadState_Suspended;