Permalink
Browse files

2009-09-25 Mark Probst <mark.probst@gmail.com>

	* object-internals.h: The Thread class is split up into Thread and
	InternalThread now.  We have exactly one InternalThread per
	thread, and at most one Thread per appdomain per thread.  Most
	data is stored in InternalThread.  All InternalThread objects live
	in the root domain.

	* class-internals.h: Add internal_thread_class to MonoDefaults.

	* appdomain.c (mono_domain_unload), attach.c (receiver_thread),
	domain.c, gc.c, icall-def.h, monitor.c, object.c, sgen-gc.c,
	socket-io.c, threadpool.c, thread-types.h, threads.c: Changes
	resulting from the split of the Thread class.

	* gc-internal.h: Prototype for new function for checking whether a
	thread is the finalizer thread.

	* appdomain.c: Corlib version bump.

2009-09-25  Mark Probst  <mark.probst@gmail.com>

	* method-to-ir.c, mini.h, mini-alpha.c, mini-amd64.c, mini-arm.c,
	mini-hppa.c, mini-ia64.c, mini-mips.c, mini-ppc.c, mini-s390.c,
	mini-s390x.c, mini-sparc.c, mini-x86.c: Thread.get_CurrentThread
	works differently now and we don't handle it in the JIT anymore.

	* mini.c, mini-exceptions.c, mini-posix.c, debug-debugger.c,
	debug-mini.c, tramp-amd64.c, tramp-x86.c: Changes resulting from
	the Thread class split.

2009-09-25  Mark Probst  <mark.probst@gmail.com>

	* xdomain-threads.c: Test for checking whether Thread is correctly
	separated between appdomains.

	* Makefile.am: Test added.

svn path=/trunk/mono/; revision=142662
  • Loading branch information...
1 parent 0473dde commit 677a2cf5da0492b37a22c15bbae722cc43c46a7e @schani schani committed Sep 25, 2009
View
@@ -1,3 +1,23 @@
+2009-09-25 Mark Probst <mark.probst@gmail.com>
+
+ * object-internals.h: The Thread class is split up into Thread and
+ InternalThread now. We have exactly one InternalThread per
+ thread, and at most one Thread per appdomain per thread. Most
+ data is stored in InternalThread. All InternalThread objects live
+ in the root domain.
+
+ * class-internals.h: Add internal_thread_class to MonoDefaults.
+
+ * appdomain.c (mono_domain_unload), attach.c (receiver_thread),
+ domain.c, gc.c, icall-def.h, monitor.c, object.c, sgen-gc.c,
+ socket-io.c, threadpool.c, thread-types.h, threads.c: Changes
+ resulting from the split of the Thread class.
+
+ * gc-internal.h: Prototype for new function for checking whether a
+ thread is the finalizer thread.
+
+ * appdomain.c: Corlib version bump.
+
2009-09-25 Rolf Bjarne Kvinge <RKvinge@novell.com>
* appdomain.c|h: Add a mono_domain_try_unload method which is
@@ -72,7 +72,7 @@
* Changes which are already detected at runtime, like the addition
* of icalls, do not require an increment.
*/
-#define MONO_CORLIB_VERSION 82
+#define MONO_CORLIB_VERSION 83
typedef struct
{
@@ -2208,7 +2208,7 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc)
/* Wait for the thread */
while ((res = WaitForSingleObjectEx (thread_handle, INFINITE, TRUE) == WAIT_IO_COMPLETION)) {
- if (mono_thread_has_appdomain_ref (mono_thread_current (), domain) && (mono_thread_interruption_requested ()))
+ if (mono_thread_internal_has_appdomain_ref (mono_thread_internal_current (), domain) && (mono_thread_interruption_requested ()))
/* The unload thread tries to abort us */
/* The icall wrapper will execute the abort */
CloseHandle (thread_handle);
View
@@ -506,7 +506,7 @@ receiver_thread (void *arg)
/* Ask the runtime to not abort this thread */
//mono_thread_current ()->flags |= MONO_THREAD_FLAG_DONT_MANAGE;
/* Ask the runtime to not wait for this thread */
- mono_thread_current ()->state |= ThreadState_Background;
+ mono_thread_internal_current ()->state |= ThreadState_Background;
while (TRUE) {
char *cmd, *agent_name, *agent_args;
@@ -982,6 +982,7 @@ typedef struct {
MonoClass *exception_class;
MonoClass *threadabortexception_class;
MonoClass *thread_class;
+ MonoClass *internal_thread_class;
MonoClass *transparent_proxy_class;
MonoClass *real_proxy_class;
MonoClass *mono_method_message_class;
View
@@ -77,8 +77,8 @@ static __thread MonoDomain * tls_appdomain MONO_TLS_FAST;
#endif
-#define GET_APPCONTEXT() (mono_thread_current ()->current_appcontext)
-#define SET_APPCONTEXT(x) MONO_OBJECT_SETREF (mono_thread_current (), current_appcontext, (x))
+#define GET_APPCONTEXT() (mono_thread_internal_current ()->current_appcontext)
+#define SET_APPCONTEXT(x) MONO_OBJECT_SETREF (mono_thread_internal_current (), current_appcontext, (x))
static guint16 appdomain_list_size = 0;
static guint16 appdomain_next = 0;
@@ -1481,6 +1481,10 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
mono_defaults.corlib, "System.Threading", "Thread");
g_assert (mono_defaults.thread_class != 0);
+ mono_defaults.internal_thread_class = mono_class_from_name (
+ mono_defaults.corlib, "System.Threading", "InternalThread");
+ g_assert (mono_defaults.internal_thread_class != 0);
+
mono_defaults.appdomain_class = mono_class_from_name (
mono_defaults.corlib, "System", "AppDomain");
g_assert (mono_defaults.appdomain_class != 0);
@@ -1760,7 +1764,7 @@ mono_domain_get ()
void
mono_domain_set_internal_with_options (MonoDomain *domain, gboolean migrate_exception)
{
- MonoThread *thread;
+ MonoInternalThread *thread;
if (mono_domain_get () == domain)
return;
@@ -1769,7 +1773,7 @@ mono_domain_set_internal_with_options (MonoDomain *domain, gboolean migrate_exce
SET_APPCONTEXT (domain->default_context);
if (migrate_exception) {
- thread = mono_thread_current ();
+ thread = mono_thread_internal_current ();
if (!thread->abort_exc)
return;
@@ -11,6 +11,7 @@
#include <glib.h>
#include <mono/metadata/object-internals.h>
+#include <mono/metadata/threads-types.h>
#include <mono/utils/gc_wrapper.h>
#define mono_domain_finalizers_lock(domain) EnterCriticalSection (&(domain)->finalizable_objects_hash_lock);
@@ -51,6 +52,8 @@ extern gboolean mono_gc_is_gc_thread (void) MONO_INTERNAL;
*/
extern gboolean mono_gc_register_thread (void *baseptr) MONO_INTERNAL;
+extern gboolean mono_gc_is_finalizer_internal_thread (MonoInternalThread *thread) MONO_INTERNAL;
+
/* only valid after the RECLAIM_START GC event and before RECLAIM_END
* Not exported in public headers, but can be linked to (unsupported).
*/
View
@@ -56,7 +56,7 @@ static CRITICAL_SECTION finalizer_mutex;
static GSList *domains_to_finalize= NULL;
static MonoMList *threads_to_finalize = NULL;
-static MonoThread *gc_thread;
+static MonoInternalThread *gc_thread;
static void object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*));
@@ -68,7 +68,7 @@ static HANDLE shutdown_event;
#endif
static void
-add_thread_to_finalize (MonoThread *thread)
+add_thread_to_finalize (MonoInternalThread *thread)
{
mono_finalizer_lock ();
if (!threads_to_finalize)
@@ -137,10 +137,10 @@ mono_gc_run_finalize (void *obj, void *data)
/* make sure the finalizer is not called again if the object is resurrected */
object_register_finalizer (obj, NULL);
- if (o->vtable->klass == mono_get_thread_class ()) {
- MonoThread *t = (MonoThread*)o;
+ if (o->vtable->klass == mono_defaults.internal_thread_class) {
+ MonoInternalThread *t = (MonoInternalThread*)o;
- if (mono_gc_is_finalizer_thread (t))
+ if (mono_gc_is_finalizer_internal_thread (t))
/* Avoid finalizing ourselves */
return;
@@ -228,7 +228,7 @@ void
mono_gc_finalize_threadpool_threads (void)
{
while (threads_to_finalize) {
- MonoThread *thread = (MonoThread*) mono_mlist_get_data (threads_to_finalize);
+ MonoInternalThread *thread = (MonoInternalThread*) mono_mlist_get_data (threads_to_finalize);
/* Force finalization of the thread. */
thread->threadpool_thread = FALSE;
@@ -336,7 +336,7 @@ mono_domain_finalize (MonoDomain *domain, guint32 timeout)
guint32 res;
HANDLE done_event;
- if (mono_thread_current () == gc_thread)
+ if (mono_thread_internal_current () == gc_thread)
/* We are called from inside a finalizer, not much we can do here */
return FALSE;
@@ -459,7 +459,7 @@ ves_icall_System_GC_WaitForPendingFinalizers (void)
if (!mono_gc_pending_finalizers ())
return;
- if (mono_thread_current () == gc_thread)
+ if (mono_thread_internal_current () == gc_thread)
/* Avoid deadlocks */
return;
@@ -1099,7 +1099,7 @@ mono_gc_cleanup (void)
if (!gc_disabled) {
ResetEvent (shutdown_event);
finished = TRUE;
- if (mono_thread_current () != gc_thread) {
+ if (mono_thread_internal_current () != gc_thread) {
mono_gc_finalize_notify ();
/* Finishing the finalizer thread, so wait a little bit... */
/* MS seems to wait for about 2 seconds */
@@ -1110,7 +1110,7 @@ mono_gc_cleanup (void)
suspend_finalizers = TRUE;
/* Try to abort the thread, in the hope that it is running managed code */
- mono_thread_stop (gc_thread);
+ mono_thread_internal_stop (gc_thread);
/* Wait for it to stop */
ret = WaitForSingleObjectEx (gc_thread->handle, 100, TRUE);
@@ -1162,6 +1162,12 @@ void mono_gc_cleanup (void)
#endif
+gboolean
+mono_gc_is_finalizer_internal_thread (MonoInternalThread *thread)
+{
+ return thread == gc_thread;
+}
+
/**
* mono_gc_is_finalizer_thread:
* @thread: the thread to test.
@@ -1175,5 +1181,5 @@ void mono_gc_cleanup (void)
gboolean
mono_gc_is_finalizer_thread (MonoThread *thread)
{
- return thread == gc_thread;
+ return mono_gc_is_finalizer_internal_thread (thread->internal_thread);
}
View
@@ -825,6 +825,9 @@ ICALL(ILOCK_19, "Increment(int&)", ves_icall_System_Threading_Interlocked_Increm
ICALL(ILOCK_20, "Increment(long&)", ves_icall_System_Threading_Interlocked_Increment_Long)
ICALL(ILOCK_21, "Read(long&)", ves_icall_System_Threading_Interlocked_Read_Long)
+ICALL_TYPE(ITHREAD, "System.Threading.InternalThread", ITHREAD_1)
+ICALL(ITHREAD_1, "Thread_free_internal", ves_icall_System_Threading_InternalThread_Thread_free_internal)
+
ICALL_TYPE(MONIT, "System.Threading.Monitor", MONIT_8)
ICALL(MONIT_8, "Enter", mono_monitor_enter)
ICALL(MONIT_1, "Exit", mono_monitor_exit)
@@ -853,34 +856,33 @@ ICALL(SEMA_2, "OpenSemaphore_internal(string,System.Security.AccessControl.Semap
ICALL(SEMA_3, "ReleaseSemaphore_internal(intptr,int,bool&)", ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal)
ICALL_TYPE(THREAD, "System.Threading.Thread", THREAD_1)
-ICALL(THREAD_1, "Abort_internal(object)", ves_icall_System_Threading_Thread_Abort)
-ICALL(THREAD_2, "ClrState", ves_icall_System_Threading_Thread_ClrState)
-ICALL(THREAD_3, "CurrentThread_internal", mono_thread_current)
+ICALL(THREAD_1, "Abort_internal(System.Threading.InternalThread,object)", ves_icall_System_Threading_Thread_Abort)
+ICALL(THREAD_2, "ClrState(System.Threading.InternalThread,System.Threading.ThreadState)", ves_icall_System_Threading_Thread_ClrState)
+ICALL(THREAD_2a, "ConstructInternalThread", ves_icall_System_Threading_Thread_ConstructInternalThread)
+ICALL(THREAD_3, "CurrentInternalThread_internal", mono_thread_internal_current)
ICALL(THREAD_4, "FreeLocalSlotValues", mono_thread_free_local_slot_values)
ICALL(THREAD_55, "GetAbortExceptionState", ves_icall_System_Threading_Thread_GetAbortExceptionState)
-ICALL(THREAD_5, "GetCachedCurrentCulture", ves_icall_System_Threading_Thread_GetCachedCurrentCulture)
-ICALL(THREAD_6, "GetCachedCurrentUICulture", ves_icall_System_Threading_Thread_GetCachedCurrentUICulture)
+ICALL(THREAD_5, "GetCachedCurrentCulture(System.Threading.InternalThread)", ves_icall_System_Threading_Thread_GetCachedCurrentCulture)
+ICALL(THREAD_6, "GetCachedCurrentUICulture(System.Threading.InternalThread)", ves_icall_System_Threading_Thread_GetCachedCurrentUICulture)
ICALL(THREAD_7, "GetDomainID", ves_icall_System_Threading_Thread_GetDomainID)
-ICALL(THREAD_8, "GetName_internal", ves_icall_System_Threading_Thread_GetName_internal)
-ICALL(THREAD_9, "GetSerializedCurrentCulture", ves_icall_System_Threading_Thread_GetSerializedCurrentCulture)
-ICALL(THREAD_10, "GetSerializedCurrentUICulture", ves_icall_System_Threading_Thread_GetSerializedCurrentUICulture)
-ICALL(THREAD_11, "GetState", ves_icall_System_Threading_Thread_GetState)
-ICALL(THREAD_53, "Interrupt_internal", ves_icall_System_Threading_Thread_Interrupt_internal)
-ICALL(THREAD_12, "Join_internal", ves_icall_System_Threading_Thread_Join_internal)
+ICALL(THREAD_8, "GetName_internal(System.Threading.InternalThread)", ves_icall_System_Threading_Thread_GetName_internal)
+ICALL(THREAD_9, "GetSerializedCurrentCulture(System.Threading.InternalThread)", ves_icall_System_Threading_Thread_GetSerializedCurrentCulture)
+ICALL(THREAD_10, "GetSerializedCurrentUICulture(System.Threading.InternalThread)", ves_icall_System_Threading_Thread_GetSerializedCurrentUICulture)
+ICALL(THREAD_11, "GetState(System.Threading.InternalThread)", ves_icall_System_Threading_Thread_GetState)
+ICALL(THREAD_53, "Interrupt_internal(System.Threading.InternalThread)", ves_icall_System_Threading_Thread_Interrupt_internal)
+ICALL(THREAD_12, "Join_internal(System.Threading.InternalThread,int,intptr)", ves_icall_System_Threading_Thread_Join_internal)
ICALL(THREAD_13, "MemoryBarrier", ves_icall_System_Threading_Thread_MemoryBarrier)
ICALL(THREAD_14, "ResetAbort_internal()", ves_icall_System_Threading_Thread_ResetAbort)
ICALL(THREAD_15, "Resume_internal()", ves_icall_System_Threading_Thread_Resume)
ICALL(THREAD_16, "SetCachedCurrentCulture", ves_icall_System_Threading_Thread_SetCachedCurrentCulture)
ICALL(THREAD_17, "SetCachedCurrentUICulture", ves_icall_System_Threading_Thread_SetCachedCurrentUICulture)
-ICALL(THREAD_18, "SetName_internal", ves_icall_System_Threading_Thread_SetName_internal)
-ICALL(THREAD_19, "SetSerializedCurrentCulture", ves_icall_System_Threading_Thread_SetSerializedCurrentCulture)
-ICALL(THREAD_20, "SetSerializedCurrentUICulture", ves_icall_System_Threading_Thread_SetSerializedCurrentUICulture)
-ICALL(THREAD_21, "SetState", ves_icall_System_Threading_Thread_SetState)
+ICALL(THREAD_18, "SetName_internal(System.Threading.InternalThread,string)", ves_icall_System_Threading_Thread_SetName_internal)
+ICALL(THREAD_19, "SetSerializedCurrentCulture(System.Threading.InternalThread,byte[])", ves_icall_System_Threading_Thread_SetSerializedCurrentCulture)
+ICALL(THREAD_20, "SetSerializedCurrentUICulture(System.Threading.InternalThread,byte[])", ves_icall_System_Threading_Thread_SetSerializedCurrentUICulture)
+ICALL(THREAD_21, "SetState(System.Threading.InternalThread,System.Threading.ThreadState)", ves_icall_System_Threading_Thread_SetState)
ICALL(THREAD_22, "Sleep_internal", ves_icall_System_Threading_Thread_Sleep_internal)
ICALL(THREAD_54, "SpinWait_nop", ves_icall_System_Threading_Thread_SpinWait_nop)
-ICALL(THREAD_23, "Suspend_internal", ves_icall_System_Threading_Thread_Suspend)
-ICALL(THREAD_24, "Thread_free_internal", ves_icall_System_Threading_Thread_Thread_free_internal)
-ICALL(THREAD_24a, "Thread_init", ves_icall_System_Threading_Thread_Thread_init)
+ICALL(THREAD_23, "Suspend_internal(System.Threading.InternalThread)", ves_icall_System_Threading_Thread_Suspend)
ICALL(THREAD_25, "Thread_internal", ves_icall_System_Threading_Thread_Thread_internal)
ICALL(THREAD_26, "VolatileRead(byte&)", ves_icall_System_Threading_Thread_VolatileRead1)
ICALL(THREAD_27, "VolatileRead(double&)", ves_icall_System_Threading_Thread_VolatileRead8)
View
@@ -384,7 +384,7 @@ mono_monitor_try_enter_internal (MonoObject *obj, guint32 ms, gboolean allow_int
guint32 then = 0, now, delta;
guint32 waitms;
guint32 ret;
- MonoThread *thread;
+ MonoInternalThread *thread;
LOCK_DEBUG (g_message("%s: (%d) Trying to lock object %p (%d ms)", __func__, id, obj, ms));
@@ -582,7 +582,7 @@ mono_monitor_try_enter_internal (MonoObject *obj, guint32 ms, gboolean allow_int
mono_perfcounters->thread_queue_len++;
mono_perfcounters->thread_queue_max++;
- thread = mono_thread_current ();
+ thread = mono_thread_internal_current ();
mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
@@ -623,7 +623,7 @@ mono_monitor_try_enter_internal (MonoObject *obj, guint32 ms, gboolean allow_int
}
} else {
if (ret == WAIT_TIMEOUT || (ret == WAIT_IO_COMPLETION && !allow_interruption)) {
- if (ret == WAIT_IO_COMPLETION && (mono_thread_test_state (mono_thread_current (), (ThreadState_StopRequested|ThreadState_SuspendRequested)))) {
+ if (ret == WAIT_IO_COMPLETION && (mono_thread_test_state (mono_thread_internal_current (), (ThreadState_StopRequested|ThreadState_SuspendRequested)))) {
/*
* We have to obey a stop/suspend request even if
* allow_interruption is FALSE to avoid hangs at shutdown.
@@ -839,7 +839,7 @@ mono_monitor_get_fast_enter_method (MonoMethod *monitor_enter_method)
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
mono_mb_emit_byte (mb, CEE_MONO_TLS);
mono_mb_emit_i4 (mb, thread_tls_offset);
- mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoThread, tid));
+ mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoInternalThread, tid));
mono_mb_emit_byte (mb, CEE_ADD);
mono_mb_emit_byte (mb, CEE_LDIND_I);
mono_mb_emit_stloc (mb, tid_loc);
@@ -980,7 +980,7 @@ mono_monitor_get_fast_exit_method (MonoMethod *monitor_exit_method)
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
mono_mb_emit_byte (mb, CEE_MONO_TLS);
mono_mb_emit_i4 (mb, thread_tls_offset);
- mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoThread, tid));
+ mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoInternalThread, tid));
mono_mb_emit_byte (mb, CEE_ADD);
mono_mb_emit_byte (mb, CEE_LDIND_I);
owned_branch = mono_mb_emit_short_branch (mb, CEE_BEQ_S);
@@ -1276,7 +1276,7 @@ ves_icall_System_Threading_Monitor_Monitor_wait (MonoObject *obj, guint32 ms)
guint32 ret;
gboolean success = FALSE;
gint32 regain;
- MonoThread *thread = mono_thread_current ();
+ MonoInternalThread *thread = mono_thread_internal_current ();
LOCK_DEBUG (g_message ("%s: (%d) Trying to wait for %p with timeout %dms", __func__, GetCurrentThreadId (), obj, ms));
@@ -6,6 +6,7 @@
#include <mono/metadata/reflection.h>
#include <mono/metadata/mempool.h>
#include <mono/metadata/class-internals.h>
+#include <mono/metadata/threads-types.h>
#include <mono/io-layer/io-layer.h>
#include "mono/utils/mono-compiler.h"
@@ -309,7 +310,7 @@ typedef struct {
MonoString *internal_method_name;
} MonoStackFrame;
-struct _MonoThread {
+struct _MonoInternalThread {
MonoObject obj;
int lock_thread_id; /* to be used as the pre-shifted thread id in thin locks */
HANDLE handle;
@@ -329,7 +330,6 @@ struct _MonoThread {
gpointer lock_data;
MonoAppContext *current_appcontext;
int stack_size;
- MonoObject *start_obj;
GSList *appdomain_refs;
/* This is modified using atomic ops, so keep it a gint32 */
gint32 interruption_requested;
@@ -349,7 +349,7 @@ struct _MonoThread {
guint32 small_id; /* A small, unique id, used for the hazard pointer table. */
MonoThreadManageCallback manage_callback;
MonoException *pending_exception;
- MonoObject *ec_to_set;
+ MonoThread *root_domain_thread;
/*
* These fields are used to avoid having to increment corlib versions
* when a new field is added to the unmanaged MonoThread structure.
@@ -361,6 +361,13 @@ struct _MonoThread {
gpointer unused6;
};
+struct _MonoThread {
+ MonoObject obj;
+ struct _MonoInternalThread *internal_thread;
+ MonoObject *start_obj;
+ MonoObject *ec_to_set;
+};
+
typedef struct {
MonoString *name;
MonoReflectionType *type;
@@ -1319,7 +1326,7 @@ int
mono_get_constant_value_from_blob (MonoDomain* domain, MonoTypeEnum type, const char *blob, void *value) MONO_INTERNAL;
void
-mono_release_type_locks (MonoThread *thread) MONO_INTERNAL;
+mono_release_type_locks (MonoInternalThread *thread) MONO_INTERNAL;
char *
mono_string_to_utf8_mp (MonoMemPool *mp, MonoString *s) MONO_INTERNAL;
Oops, something went wrong.

0 comments on commit 677a2cf

Please sign in to comment.