IO threads have their own name
[mono.git] / mono / metadata / threadpool.c
index 0ca4889825800f75f5fa54929e6227d50dff50ba..2270d93ad6407a79cf72ece97b3c553c0c4b4a55 100644 (file)
@@ -64,6 +64,7 @@
                        } while (1)
 
 #define SPIN_UNLOCK(i) i = 0
+#define SMALL_STACK (128 * (sizeof (gpointer) / 4) * 1024)
 
 /* DEBUG: prints tp data every 2s */
 #undef DEBUG 
@@ -492,7 +493,6 @@ static void
 socket_io_init (SocketIOData *data)
 {
        int inited;
-       guint32 stack_size;
 
        if (data->inited >= 2) // 2 -> initialized, 3-> cleaned up
                return;
@@ -519,12 +519,10 @@ socket_io_init (SocketIOData *data)
                data->event_system = POLL_BACKEND;
 
        init_event_system (data);
-       stack_size = mono_threads_get_default_stacksize ();
-       mono_threads_set_default_stacksize (128 * (sizeof (gpointer) / 4) * 1024);
-       mono_thread_create_internal (mono_get_root_domain (), data->wait, data, TRUE);
-       mono_threads_set_default_stacksize (stack_size);
+       mono_thread_create_internal (mono_get_root_domain (), data->wait, data, TRUE, SMALL_STACK);
        LeaveCriticalSection (&data->io_lock);
        data->inited = 2;
+       mono_thread_create_internal (mono_get_root_domain (), threadpool_start_idle_threads, &async_io_tp, TRUE, SMALL_STACK);
 }
 
 static void
@@ -660,9 +658,9 @@ static void
 threadpool_start_idle_threads (ThreadPool *tp)
 {
        int n;
+       guint32 stack_size;
 
-       if (tp->pool_status == 1 && !tp->is_io)
-               mono_thread_create_internal (mono_get_root_domain (), monitor_thread, tp, TRUE);
+       stack_size = (!tp->is_io) ? 0 : SMALL_STACK;
        do {
                while (1) {
                        n = tp->nthreads;
@@ -672,7 +670,7 @@ threadpool_start_idle_threads (ThreadPool *tp)
                                break;
                }
                mono_perfcounter_update_value (tp->pc_nthreads, TRUE, 1);
-               mono_thread_create_internal (mono_get_root_domain (), tp->async_invoke, tp, TRUE);
+               mono_thread_create_internal (mono_get_root_domain (), tp->async_invoke, tp, TRUE, stack_size);
                SleepEx (100, TRUE);
        } while (1);
 }
@@ -761,7 +759,7 @@ monitor_thread (gpointer data)
 
        tp = data;
        thread = mono_thread_internal_current ();
-       ves_icall_System_Threading_Thread_SetName_internal (thread, mono_string_new (mono_domain_get (), "Threapool monitor"));
+       ves_icall_System_Threading_Thread_SetName_internal (thread, mono_string_new (mono_domain_get (), "Threadpool monitor"));
        while (1) {
                ms = 500;
                do {
@@ -991,11 +989,13 @@ static gboolean
 threadpool_start_thread (ThreadPool *tp)
 {
        gint n;
+       guint32 stack_size;
 
+       stack_size = (!tp->is_io) ? 0 : SMALL_STACK;
        while (!mono_runtime_is_shutting_down () && (n = tp->nthreads) < tp->max_threads) {
                if (InterlockedCompareExchange (&tp->nthreads, n + 1, n) == n) {
                        mono_perfcounter_update_value (tp->pc_nthreads, TRUE, 1);
-                       mono_thread_create_internal (mono_get_root_domain (), tp->async_invoke, tp, TRUE);
+                       mono_thread_create_internal (mono_get_root_domain (), tp->async_invoke, tp, TRUE, stack_size);
                        return TRUE;
                }
        }
@@ -1032,8 +1032,14 @@ threadpool_append_jobs (ThreadPool *tp, MonoObject **jobs, gint njobs)
        if (mono_runtime_is_shutting_down ())
                return;
 
-       if (tp->pool_status == 0 && InterlockedCompareExchange (&tp->pool_status, 1, 0) == 0)
-               mono_thread_create_internal (mono_get_root_domain (), threadpool_start_idle_threads, tp, TRUE);
+       if (tp->pool_status == 0 && InterlockedCompareExchange (&tp->pool_status, 1, 0) == 0) {
+               if (!tp->is_io)
+                       mono_thread_create_internal (mono_get_root_domain (), monitor_thread, tp, TRUE, SMALL_STACK);
+               /* Create on demand up to min_threads to avoid startup penalty for apps that don't use
+                * the threadpool that much
+               * mono_thread_create_internal (mono_get_root_domain (), threadpool_start_idle_threads, tp, TRUE, SMALL_STACK);
+               */
+       }
 
        for (i = 0; i < njobs; i++) {
                ar = jobs [i];
@@ -1326,6 +1332,7 @@ async_invoke_thread (gpointer data)
        MonoWSQ *wsq;
        ThreadPool *tp;
        gboolean must_die;
+       const gchar *name;
   
        tp = data;
        wsq = NULL;
@@ -1335,7 +1342,8 @@ async_invoke_thread (gpointer data)
        thread = mono_thread_internal_current ();
 
        mono_profiler_thread_start (thread->tid);
-       ves_icall_System_Threading_Thread_SetName_internal (thread, mono_string_new (mono_domain_get (), "Threapool worker"));
+       name = (tp->is_io) ? "IO Threadpool worker" : "Threadpool worker";
+       ves_icall_System_Threading_Thread_SetName_internal (thread, mono_string_new (mono_domain_get (), name));
 
        if (tp_start_func)
                tp_start_func (tp_hooks_user_data);
@@ -1537,9 +1545,9 @@ ves_icall_System_Threading_ThreadPool_SetMinThreads (gint workerThreads, gint co
        InterlockedExchange (&async_tp.min_threads, workerThreads);
        InterlockedExchange (&async_io_tp.min_threads, completionPortThreads);
        if (workerThreads > async_tp.nthreads)
-               mono_thread_create_internal (mono_get_root_domain (), threadpool_start_idle_threads, &async_tp, TRUE);
+               mono_thread_create_internal (mono_get_root_domain (), threadpool_start_idle_threads, &async_tp, TRUE, SMALL_STACK);
        if (completionPortThreads > async_io_tp.nthreads)
-               mono_thread_create_internal (mono_get_root_domain (), threadpool_start_idle_threads, &async_io_tp, TRUE);
+               mono_thread_create_internal (mono_get_root_domain (), threadpool_start_idle_threads, &async_io_tp, TRUE, SMALL_STACK);
        return TRUE;
 }