X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Futils%2Fmono-threads-posix.c;h=9ee2a77402de20bebbca6cabbd61ec0a3f7917bd;hb=eeb5d4c670b18885d4f575136e348df324c46de8;hp=7d656132b5908b35b491f4c439eefa66c83cd243;hpb=d6f7d6199c5848610d4e01be084b44bea0551adb;p=mono.git diff --git a/mono/utils/mono-threads-posix.c b/mono/utils/mono-threads-posix.c index 7d656132b59..9ee2a77402d 100644 --- a/mono/utils/mono-threads-posix.c +++ b/mono/utils/mono-threads-posix.c @@ -1,5 +1,6 @@ -/* - * mono-threads-posix.c: Low-level threading, posix version +/** + * \file + * Low-level threading, posix version * * Author: * Rodrigo Kumpera (kumpera@gmail.com) @@ -15,10 +16,9 @@ #endif #include -#include #include #include -#include +#include #include @@ -36,132 +36,92 @@ extern int tkill (pid_t tid, int signal); #include -#if defined(__native_client__) -void nacl_shutdown_gc_thread(void); -#endif - -void -mono_threads_platform_register (MonoThreadInfo *info) -{ - gpointer thread_handle; - - thread_handle = mono_w32handle_new (MONO_W32HANDLE_THREAD, NULL); - if (thread_handle == INVALID_HANDLE_VALUE) - g_error ("%s: failed to create handle", __func__); - - g_assert (!info->handle); - info->handle = thread_handle; -} - -int -mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize stack_size, MonoNativeThreadId *out_tid) +gboolean +mono_thread_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize* const stack_size, MonoNativeThreadId *tid) { pthread_attr_t attr; pthread_t thread; - int policy; - struct sched_param param; gint res; + gsize set_stack_size; res = pthread_attr_init (&attr); - g_assert (!res); + if (res != 0) + g_error ("%s: pthread_attr_init failed, error: \"%s\" (%d)", __func__, g_strerror (res), 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); - g_assert (!res); -#endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */ - - memset (¶m, 0, sizeof (param)); - - res = pthread_attr_getschedpolicy (&attr, &policy); + res = pthread_attr_setstacksize (&attr, set_stack_size); if (res != 0) - g_error ("%s: pthread_attr_getschedpolicy failed, error: \"%s\" (%d)", g_strerror (res), res); + g_error ("%s: pthread_attr_setstacksize failed, error: \"%s\" (%d)", __func__, g_strerror (res), res); +#endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */ -#ifdef _POSIX_PRIORITY_SCHEDULING - int max, min; + /* Actually start the thread */ + res = mono_gc_pthread_create (&thread, &attr, (gpointer (*)(gpointer)) thread_fn, thread_data); + if (res) { + res = pthread_attr_destroy (&attr); + if (res != 0) + g_error ("%s: pthread_attr_destroy failed, error: \"%s\" (%d)", __func__, g_strerror (res), res); - /* Necessary to get valid priority range */ + return FALSE; + } - min = sched_get_priority_min (policy); - max = sched_get_priority_max (policy); + if (tid) + *tid = thread; - if (max > 0 && min >= 0 && max > min) - param.sched_priority = (max - min) / 2 + min; - else -#endif - { - switch (policy) { - case SCHED_FIFO: - case SCHED_RR: - param.sched_priority = 50; - break; -#ifdef SCHED_BATCH - case SCHED_BATCH: -#endif - case SCHED_OTHER: - param.sched_priority = 0; - break; - default: - g_error ("%s: unknown policy %d", __func__, policy); - } + if (stack_size) { + res = pthread_attr_getstacksize (&attr, stack_size); + if (res != 0) + g_error ("%s: pthread_attr_getstacksize failed, error: \"%s\" (%d)", __func__, g_strerror (res), res); } - res = pthread_attr_setschedparam (&attr, ¶m); + res = pthread_attr_destroy (&attr); if (res != 0) - g_error ("%s: pthread_attr_setschedparam failed, error: \"%s\" (%d)", g_strerror (res), res); - - /* Actually start the thread */ - res = mono_gc_pthread_create (&thread, &attr, (gpointer (*)(gpointer)) thread_fn, thread_data); - if (res) - return -1; + g_error ("%s: pthread_attr_destroy failed, error: \"%s\" (%d)", __func__, g_strerror (res), res); - if (out_tid) - *out_tid = thread; + return TRUE; +} - return 0; +void +mono_threads_platform_init (void) +{ } gboolean -mono_threads_platform_yield (void) +mono_threads_platform_in_critical_region (MonoNativeThreadId tid) { - return sched_yield () == 0; + return FALSE; } -void -mono_threads_platform_exit (int exit_code) +gboolean +mono_threads_platform_yield (void) { -#if defined(__native_client__) - nacl_shutdown_gc_thread(); -#endif - - mono_thread_info_detach (); - - pthread_exit (NULL); + return sched_yield () == 0; } void -mono_threads_platform_unregister (MonoThreadInfo *info) +mono_threads_platform_exit (gsize exit_code) { - g_assert (info->handle); - - /* The thread is no longer active, so unref it */ - mono_w32handle_unref (info->handle); - info->handle = NULL; + pthread_exit ((gpointer) exit_code); } int @@ -178,28 +138,6 @@ mono_threads_get_max_stack_size (void) return (int)lim.rlim_max; } -gpointer -mono_threads_platform_duplicate_handle (MonoThreadInfo *info) -{ - g_assert (info->handle); - mono_w32handle_ref (info->handle); - return info->handle; -} - -HANDLE -mono_threads_platform_open_thread_handle (HANDLE handle, MonoNativeThreadId tid) -{ - mono_w32handle_ref (handle); - - return handle; -} - -void -mono_threads_platform_close_thread_handle (HANDLE handle) -{ - mono_w32handle_unref (handle); -} - int mono_threads_pthread_kill (MonoThreadInfo *info, int signum) { @@ -261,8 +199,8 @@ mono_native_thread_set_name (MonoNativeThreadId tid, const char *name) } else { char n [63]; - strncpy (n, name, 63); - n [62] = '\0'; + memcpy (n, name, sizeof (n) - 1); + n [sizeof (n) - 1] = '\0'; pthread_setname_np (n); } #elif defined (__NetBSD__) @@ -271,8 +209,8 @@ mono_native_thread_set_name (MonoNativeThreadId tid, const char *name) } else { char n [PTHREAD_MAX_NAMELEN_NP]; - strncpy (n, name, PTHREAD_MAX_NAMELEN_NP); - n [PTHREAD_MAX_NAMELEN_NP - 1] = '\0'; + memcpy (n, name, sizeof (n) - 1); + n [sizeof (n) - 1] = '\0'; pthread_setname_np (tid, "%s", (void*)n); } #elif defined (HAVE_PTHREAD_SETNAME_NP) @@ -281,8 +219,8 @@ mono_native_thread_set_name (MonoNativeThreadId tid, const char *name) } else { char n [16]; - strncpy (n, name, 16); - n [15] = '\0'; + memcpy (n, name, sizeof (n) - 1); + n [sizeof (n) - 1] = '\0'; pthread_setname_np (tid, n); } #endif @@ -296,56 +234,6 @@ mono_native_thread_join (MonoNativeThreadId tid) return !pthread_join (tid, &res); } -void -mono_threads_platform_set_exited (gpointer handle) -{ - int thr_ret; - - g_assert (handle); - if (mono_w32handle_issignalled (handle)) - g_error ("%s: handle %p thread %p has already exited, it's handle is signalled", __func__, handle, mono_native_thread_id_get ()); - if (mono_w32handle_get_type (handle) == MONO_W32HANDLE_UNUSED) - g_error ("%s: handle %p thread %p has already exited, it's handle type is 'unused'", __func__, handle, mono_native_thread_id_get ()); - - thr_ret = mono_w32handle_lock_handle (handle); - g_assert (thr_ret == 0); - - mono_w32handle_set_signal_state (handle, TRUE, TRUE); - - thr_ret = mono_w32handle_unlock_handle (handle); - g_assert (thr_ret == 0); -} - -static const gchar* thread_typename (void) -{ - return "Thread"; -} - -static gsize thread_typesize (void) -{ - return 0; -} - -static MonoW32HandleOps thread_ops = { - NULL, /* close */ - NULL, /* signal */ - NULL, /* own */ - NULL, /* is_owned */ - NULL, /* special_wait */ - NULL, /* prewait */ - NULL, /* details */ - thread_typename, /* typename */ - thread_typesize, /* typesize */ -}; - -void -mono_threads_platform_init (void) -{ - mono_w32handle_register_ops (MONO_W32HANDLE_THREAD, &thread_ops); - - mono_w32handle_register_capabilities (MONO_W32HANDLE_THREAD, MONO_W32HANDLE_CAP_WAIT); -} - #endif /* defined(_POSIX_VERSION) || defined(__native_client__) */ #if defined(USE_POSIX_BACKEND) @@ -353,7 +241,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); @@ -377,8 +265,24 @@ This begins async resume. This function must do the following: 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; + int sig = mono_threads_suspend_get_restart_signal (); + + if (!mono_threads_pthread_kill (info, sig)) { + mono_threads_add_to_pending_operation_set (info); + return TRUE; + } + return FALSE; +} + +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); + } } void @@ -397,7 +301,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) */