View | Details | Raw Unified | Return to bug 337383
Collapse All | Expand All

(-)metadata/gc-internal.h (+2 lines)
Lines 88-93 Link Here
88
void  mono_gc_deregister_root (char* addr) MONO_INTERNAL;
88
void  mono_gc_deregister_root (char* addr) MONO_INTERNAL;
89
int   mono_gc_finalizers_for_domain (MonoDomain *domain, MonoObject **out_array, int out_size) MONO_INTERNAL;
89
int   mono_gc_finalizers_for_domain (MonoDomain *domain, MonoObject **out_array, int out_size) MONO_INTERNAL;
90
90
91
void  mono_gc_finalize_threadpool_threads (void) MONO_INTERNAL;
92
91
/* fast allocation support */
93
/* fast allocation support */
92
MonoMethod* mono_gc_get_managed_allocator (MonoVTable *vtable, gboolean for_box) MONO_INTERNAL;
94
MonoMethod* mono_gc_get_managed_allocator (MonoVTable *vtable, gboolean for_box) MONO_INTERNAL;
93
int mono_gc_get_managed_allocator_type (MonoMethod *managed_alloc) MONO_INTERNAL;
95
int mono_gc_get_managed_allocator_type (MonoMethod *managed_alloc) MONO_INTERNAL;
(-)metadata/threads.c (-2 / +11 lines)
Lines 602-608 Link Here
602
	return default_stacksize;
602
	return default_stacksize;
603
}
603
}
604
604
605
void mono_thread_create (MonoDomain *domain, gpointer func, gpointer arg)
605
void mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gboolean threadpool_thread)
606
{
606
{
607
	MonoThread *thread;
607
	MonoThread *thread;
608
	HANDLE thread_handle;
608
	HANDLE thread_handle;
Lines 637-648 Link Here
637
637
638
	thread->synch_cs = g_new0 (CRITICAL_SECTION, 1);
638
	thread->synch_cs = g_new0 (CRITICAL_SECTION, 1);
639
	InitializeCriticalSection (thread->synch_cs);
639
	InitializeCriticalSection (thread->synch_cs);
640
						  
640
641
	thread->threadpool_thread = threadpool_thread;
642
641
	handle_store(thread);
643
	handle_store(thread);
642
644
643
	ResumeThread (thread_handle);
645
	ResumeThread (thread_handle);
644
}
646
}
645
647
648
void
649
mono_thread_create (MonoDomain *domain, gpointer func, gpointer arg)
650
{
651
	mono_thread_create_internal (domain, func, arg, FALSE);
652
}
653
646
/*
654
/*
647
 * mono_thread_get_stack_bounds:
655
 * mono_thread_get_stack_bounds:
648
 *
656
 *
Lines 890-895 Link Here
890
898
891
	DeleteCriticalSection (this->synch_cs);
899
	DeleteCriticalSection (this->synch_cs);
892
	g_free (this->synch_cs);
900
	g_free (this->synch_cs);
901
	this->synch_cs = NULL;
893
}
902
}
894
903
895
static void mono_thread_start (MonoThread *thread)
904
static void mono_thread_start (MonoThread *thread)
(-)metadata/threadpool.c (-6 / +4 lines)
Lines 235-241 Link Here
235
	MonoDomain *domain;
235
	MonoDomain *domain;
236
	MonoThread *thread;
236
	MonoThread *thread;
237
	thread = mono_thread_current ();
237
	thread = mono_thread_current ();
238
	thread->threadpool_thread = TRUE;
239
	ves_icall_System_Threading_Thread_SetState (thread, ThreadState_Background);
238
	ves_icall_System_Threading_Thread_SetState (thread, ThreadState_Background);
240
239
241
	for (;;) {
240
	for (;;) {
Lines 324-330 Link Here
324
		InterlockedIncrement (&busy_io_worker_threads);
323
		InterlockedIncrement (&busy_io_worker_threads);
325
		InterlockedIncrement (&io_worker_threads);
324
		InterlockedIncrement (&io_worker_threads);
326
		domain = ((ares) ? ((MonoObject *) ares)->vtable->domain : mono_domain_get ());
325
		domain = ((ares) ? ((MonoObject *) ares)->vtable->domain : mono_domain_get ());
327
		mono_thread_create (mono_get_root_domain (), async_invoke_io_thread, ares);
326
		mono_thread_create_internal (mono_get_root_domain (), async_invoke_io_thread, ares, TRUE);
328
	} else {
327
	} else {
329
		append_job (&io_queue_lock, &async_io_queue, (MonoObject*)ares);
328
		append_job (&io_queue_lock, &async_io_queue, (MonoObject*)ares);
330
		ReleaseSemaphore (io_job_added, 1, NULL);
329
		ReleaseSemaphore (io_job_added, 1, NULL);
Lines 396-402 Link Here
396
	MonoThread *thread;
395
	MonoThread *thread;
397
396
398
	thread = mono_thread_current ();
397
	thread = mono_thread_current ();
399
	thread->threadpool_thread = TRUE;
400
	ves_icall_System_Threading_Thread_SetState (thread, ThreadState_Background);
398
	ves_icall_System_Threading_Thread_SetState (thread, ThreadState_Background);
401
399
402
	allocated = INITIAL_POLLFD_SIZE;
400
	allocated = INITIAL_POLLFD_SIZE;
Lines 766-776 Link Here
766
	g_assert (io_job_added != NULL);
764
	g_assert (io_job_added != NULL);
767
	InitializeCriticalSection (&io_queue_lock);
765
	InitializeCriticalSection (&io_queue_lock);
768
	if (data->epoll_disabled) {
766
	if (data->epoll_disabled) {
769
		mono_thread_create (mono_get_root_domain (), socket_io_poll_main, data);
767
		mono_thread_create_internal (mono_get_root_domain (), socket_io_poll_main, data, TRUE);
770
	}
768
	}
771
#ifdef HAVE_EPOLL
769
#ifdef HAVE_EPOLL
772
	else {
770
	else {
773
		mono_thread_create (mono_get_root_domain (), socket_io_epoll_main, data);
771
		mono_thread_create_internal (mono_get_root_domain (), socket_io_epoll_main, data, TRUE);
774
	}
772
	}
775
#endif
773
#endif
776
	InterlockedCompareExchange (&data->inited, 1, 0);
774
	InterlockedCompareExchange (&data->inited, 1, 0);
Lines 1053-1059 Link Here
1053
	    worker < mono_max_worker_threads) {
1051
	    worker < mono_max_worker_threads) {
1054
		InterlockedIncrement (&mono_worker_threads);
1052
		InterlockedIncrement (&mono_worker_threads);
1055
		InterlockedIncrement (&busy_worker_threads);
1053
		InterlockedIncrement (&busy_worker_threads);
1056
		mono_thread_create (mono_get_root_domain (), async_invoke_thread, ares);
1054
		mono_thread_create_internal (mono_get_root_domain (), async_invoke_thread, ares, TRUE);
1057
	} else {
1055
	} else {
1058
		append_job (&mono_delegate_section, &async_call_queue, (MonoObject*)ares);
1056
		append_job (&mono_delegate_section, &async_call_queue, (MonoObject*)ares);
1059
		ReleaseSemaphore (job_added, 1, NULL);
1057
		ReleaseSemaphore (job_added, 1, NULL);
(-)metadata/threads-types.h (+2 lines)
Lines 42-47 Link Here
42
#define SPECIAL_STATIC_THREAD 1
42
#define SPECIAL_STATIC_THREAD 1
43
#define SPECIAL_STATIC_CONTEXT 2
43
#define SPECIAL_STATIC_CONTEXT 2
44
44
45
extern void mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gboolean threadpool_thread) MONO_INTERNAL;
46
45
extern HANDLE ves_icall_System_Threading_Thread_Thread_internal(MonoThread *this_obj, MonoObject *start) MONO_INTERNAL;
47
extern HANDLE ves_icall_System_Threading_Thread_Thread_internal(MonoThread *this_obj, MonoObject *start) MONO_INTERNAL;
46
extern void ves_icall_System_Threading_Thread_Thread_init(MonoThread *this_obj) MONO_INTERNAL;
48
extern void ves_icall_System_Threading_Thread_Thread_init(MonoThread *this_obj) MONO_INTERNAL;
47
extern void ves_icall_System_Threading_Thread_Thread_free_internal(MonoThread *this_obj, HANDLE thread) MONO_INTERNAL;
49
extern void ves_icall_System_Threading_Thread_Thread_free_internal(MonoThread *this_obj, HANDLE thread) MONO_INTERNAL;
(-)metadata/gc.c (-2 / +35 lines)
Lines 41-46 Link Here
41
static CRITICAL_SECTION finalizer_mutex;
41
static CRITICAL_SECTION finalizer_mutex;
42
42
43
static GSList *domains_to_finalize= NULL;
43
static GSList *domains_to_finalize= NULL;
44
static GSList *threads_to_finalize = NULL;
44
45
45
static MonoThread *gc_thread;
46
static MonoThread *gc_thread;
46
47
Lines 52-57 Link Here
52
static HANDLE thread_started_event;
53
static HANDLE thread_started_event;
53
#endif
54
#endif
54
55
56
static void
57
add_thread_to_finalize (MonoThread *thread)
58
{
59
	threads_to_finalize = g_slist_append (threads_to_finalize, thread);
60
}
61
55
/* 
62
/* 
56
 * actually, we might want to queue the finalize requests in a separate thread,
63
 * actually, we might want to queue the finalize requests in a separate thread,
57
 * but we need to be careful about the execution domain of the thread...
64
 * but we need to be careful about the execution domain of the thread...
Lines 79-89 Link Here
79
	/* make sure the finalizer is not called again if the object is resurrected */
86
	/* make sure the finalizer is not called again if the object is resurrected */
80
	object_register_finalizer (obj, NULL);
87
	object_register_finalizer (obj, NULL);
81
88
82
	if (o->vtable->klass == mono_get_thread_class ())
89
	if (o->vtable->klass == mono_get_thread_class ()) {
83
		if (mono_gc_is_finalizer_thread ((MonoThread*)o))
90
		MonoThread *t = (MonoThread*)o;
91
92
		if (mono_gc_is_finalizer_thread (t))
84
			/* Avoid finalizing ourselves */
93
			/* Avoid finalizing ourselves */
85
			return;
94
			return;
86
95
96
		if (t->threadpool_thread) {
97
			/* Don't finalize threadpool threads - they're
98
			   finalized when the threadpool shuts down. */
99
			add_thread_to_finalize (t);
100
			return;
101
		}
102
	}
103
87
	/* speedup later... and use a timeout */
104
	/* speedup later... and use a timeout */
88
	/* g_print ("Finalize run on %p %s.%s\n", o, mono_object_class (o)->name_space, mono_object_class (o)->name); */
105
	/* g_print ("Finalize run on %p %s.%s\n", o, mono_object_class (o)->name_space, mono_object_class (o)->name); */
89
106
Lines 119-124 Link Here
119
	}
136
	}
120
}
137
}
121
138
139
void
140
mono_gc_finalize_threadpool_threads (void)
141
{
142
	while (threads_to_finalize) {
143
		MonoThread *thread = threads_to_finalize->data;
144
145
		/* Force finalization of the thread. */
146
		thread->threadpool_thread = FALSE;
147
		mono_object_register_finalizer ((MonoObject*)thread);
148
149
		run_finalize (thread, NULL);
150
151
		threads_to_finalize = g_slist_remove (threads_to_finalize, thread);
152
	}
153
}
154
122
gpointer
155
gpointer
123
mono_gc_out_of_memory (size_t size)
156
mono_gc_out_of_memory (size_t size)
124
{
157
{
(-)mini/mini.c (-1 / +4 lines)
Lines 12509-12515 Link Here
12509
	 * fully working (mono_domain_finalize may invoke managed finalizers
12509
	 * fully working (mono_domain_finalize may invoke managed finalizers
12510
	 * and mono_runtime_cleanup will wait for other threads to finish).
12510
	 * and mono_runtime_cleanup will wait for other threads to finish).
12511
	 */
12511
	 */
12512
	mono_domain_finalize (domain, 2000);
12512
	if (mono_domain_finalize (domain, 2000) && domain == mono_get_root_domain ()) {
12513
		mono_thread_pool_cleanup ();
12514
		mono_gc_finalize_threadpool_threads ();
12515
	}
12513
12516
12514
	/* This accesses metadata so needs to be called before runtime shutdown */
12517
	/* This accesses metadata so needs to be called before runtime shutdown */
12515
	print_jit_stats ();
12518
	print_jit_stats ();

Return to bug 337383