Merge pull request #3769 from evincarofautumn/fix-verify-before-allocs
[mono.git] / mono / utils / mono-threads-posix.c
index 7d656132b5908b35b491f4c439eefa66c83cd243..be440711fb3bfcbdf3be365bd25876045dfe8bf5 100644 (file)
 #endif
 
 #include <mono/utils/mono-threads.h>
-#include <mono/utils/mono-threads-posix-signals.h>
 #include <mono/utils/mono-coop-semaphore.h>
 #include <mono/metadata/gc-internals.h>
 #include <mono/utils/w32handle.h>
+#include <mono/utils/mono-threads-debug.h>
 
 #include <errno.h>
 
@@ -54,35 +54,42 @@ mono_threads_platform_register (MonoThreadInfo *info)
 }
 
 int
-mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize stack_size, MonoNativeThreadId *out_tid)
+mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize* const stack_size, MonoNativeThreadId *out_tid)
 {
        pthread_attr_t attr;
        pthread_t thread;
        int policy;
        struct sched_param param;
        gint res;
+       gsize set_stack_size;
+       size_t min_size;
 
        res = pthread_attr_init (&attr);
        g_assert (!res);
 
+       if (stack_size)
+               set_stack_size = *stack_size;
+       else
+               set_stack_size = 0;
+
 #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
-       if (stack_size == 0) {
+       if (set_stack_size == 0) {
 #if HAVE_VALGRIND_MEMCHECK_H
                if (RUNNING_ON_VALGRIND)
-                       stack_size = 1 << 20;
+                       set_stack_size = 1 << 20;
                else
-                       stack_size = (SIZEOF_VOID_P / 4) * 1024 * 1024;
+                       set_stack_size = (SIZEOF_VOID_P / 4) * 1024 * 1024;
 #else
-               stack_size = (SIZEOF_VOID_P / 4) * 1024 * 1024;
+               set_stack_size = (SIZEOF_VOID_P / 4) * 1024 * 1024;
 #endif
        }
 
 #ifdef PTHREAD_STACK_MIN
-       if (stack_size < PTHREAD_STACK_MIN)
-               stack_size = PTHREAD_STACK_MIN;
+       if (set_stack_size < PTHREAD_STACK_MIN)
+               set_stack_size = PTHREAD_STACK_MIN;
 #endif
 
-       res = pthread_attr_setstacksize (&attr, stack_size);
+       res = pthread_attr_setstacksize (&attr, set_stack_size);
        g_assert (!res);
 #endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */
 
@@ -125,6 +132,14 @@ mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_
        if (res != 0)
                g_error ("%s: pthread_attr_setschedparam failed, error: \"%s\" (%d)", g_strerror (res), res);
 
+       if (stack_size) {
+               res = pthread_attr_getstacksize (&attr, &min_size);
+               if (res != 0)
+                       g_error ("%s: pthread_attr_getstacksize failed, error: \"%s\" (%d)", g_strerror (res), res);
+               else
+                       *stack_size = min_size;
+       }
+
        /* Actually start the thread */
        res = mono_gc_pthread_create (&thread, &attr, (gpointer (*)(gpointer)) thread_fn, thread_data);
        if (res)
@@ -353,7 +368,7 @@ mono_threads_platform_init (void)
 gboolean
 mono_threads_suspend_begin_async_suspend (MonoThreadInfo *info, gboolean interrupt_kernel)
 {
-       int sig = interrupt_kernel ? mono_threads_posix_get_abort_signal () :  mono_threads_posix_get_suspend_signal ();
+       int sig = interrupt_kernel ? mono_threads_suspend_get_abort_signal () :  mono_threads_suspend_get_suspend_signal ();
 
        if (!mono_threads_pthread_kill (info, sig)) {
                mono_threads_add_to_pending_operation_set (info);
@@ -378,7 +393,24 @@ gboolean
 mono_threads_suspend_begin_async_resume (MonoThreadInfo *info)
 {
        mono_threads_add_to_pending_operation_set (info);
-       return mono_threads_pthread_kill (info, mono_threads_posix_get_restart_signal ()) == 0;
+       return mono_threads_pthread_kill (info, mono_threads_suspend_get_restart_signal ()) == 0;
+}
+
+void
+mono_threads_suspend_abort_syscall (MonoThreadInfo *info)
+{
+       /* We signal a thread to break it from the current syscall.
+        * This signal should not be interpreted as a suspend request. */
+       info->syscall_break_signal = TRUE;
+       if (mono_threads_pthread_kill (info, mono_threads_suspend_get_abort_signal ()) == 0) {
+               mono_threads_add_to_pending_operation_set (info);
+       }
+}
+
+gboolean
+mono_threads_suspend_needs_abort_syscall (void)
+{
+       return TRUE;
 }
 
 void
@@ -397,7 +429,6 @@ mono_threads_suspend_free (MonoThreadInfo *info)
 void
 mono_threads_suspend_init (void)
 {
-       mono_threads_posix_init_signals (MONO_THREADS_POSIX_INIT_SIGNALS_SUSPEND_RESTART);
 }
 
 #endif /* defined(USE_POSIX_BACKEND) */