summaryrefslogtreecommitdiff
path: root/mono/metadata/sgen-os-posix.c
diff options
context:
space:
mode:
Diffstat (limited to 'mono/metadata/sgen-os-posix.c')
-rw-r--r--mono/metadata/sgen-os-posix.c71
1 files changed, 11 insertions, 60 deletions
diff --git a/mono/metadata/sgen-os-posix.c b/mono/metadata/sgen-os-posix.c
index 15f7afa1b0..b0270c049c 100644
--- a/mono/metadata/sgen-os-posix.c
+++ b/mono/metadata/sgen-os-posix.c
@@ -34,6 +34,7 @@
#include "metadata/gc-internal.h"
#include "metadata/sgen-archdep.h"
#include "metadata/object-internals.h"
+#include "utils/mono-signal-handler.h"
#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__)
const static int suspend_signal_num = SIGXFSZ;
@@ -57,17 +58,9 @@ suspend_thread (SgenThreadInfo *info, void *context)
#endif
gpointer stack_start;
- /*
- * It's possible that a dying thread is parked via
- * sgen_park_current_thread_if_doing_handshake(), and, while parked, STW tries to
- * suspend it again. In that case doing_handshake will not be set anymore, and the
- * "nested" suspend must be ignored.
- */
- if (!info->doing_handshake)
- return;
-
info->stopped_domain = mono_domain_get ();
info->stopped_ip = context ? (gpointer) ARCH_SIGCTX_IP (context) : NULL;
+ info->signal = 0;
stop_count = sgen_global_stop_count;
/* duplicate signal */
if (0 && info->stop_count == stop_count)
@@ -118,7 +111,7 @@ suspend_thread (SgenThreadInfo *info, void *context)
do {
info->signal = 0;
sigsuspend (&suspend_signal_mask);
- } while (info->signal != restart_signal_num && info->doing_handshake);
+ } while (info->signal != restart_signal_num);
/* Unblock the restart signal. */
pthread_sigmask (SIG_UNBLOCK, &suspend_ack_signal_mask, NULL);
@@ -129,49 +122,25 @@ suspend_thread (SgenThreadInfo *info, void *context)
}
/* LOCKING: assumes the GC lock is held (by the stopping thread) */
-static void
-suspend_handler (int sig, siginfo_t *siginfo, void *context)
+MONO_SIGNAL_HANDLER_FUNC (static, suspend_handler, (int sig, siginfo_t *siginfo, void *context))
{
SgenThreadInfo *info;
int old_errno = errno;
info = mono_thread_info_current ();
-
- if (info) {
- suspend_thread (info, context);
- } else {
- /* This can happen while a thread is dying */
- //g_print ("no thread info in suspend\n");
- }
+ suspend_thread (info, context);
errno = old_errno;
}
-static void
-restart_handler (int sig)
+MONO_SIGNAL_HANDLER_FUNC (static, restart_handler, (int sig))
{
SgenThreadInfo *info;
int old_errno = errno;
info = mono_thread_info_current ();
- /*
- If the thread info is null is means we're currently in the process of cleaning up,
- the pthread destructor has already kicked in and it has explicitly invoked the suspend handler.
-
- This means this thread has been suspended, TLS is dead, so the only option we have is to
- rely on pthread_self () and seatch over the thread list.
- */
- if (!info)
- info = (SgenThreadInfo*)mono_thread_info_lookup (pthread_self ());
-
- /*
- * If a thread is dying there might be no thread info. In
- * that case we rely on info->doing_handshake.
- */
- if (info) {
- info->signal = restart_signal_num;
- SGEN_LOG (4, "Restart handler in %p %p", info, (gpointer)mono_native_thread_id_get ());
- }
+ info->signal = restart_signal_num;
+ SGEN_LOG (4, "Restart handler in %p %p", info, (gpointer)mono_native_thread_id_get ());
errno = old_errno;
}
@@ -201,16 +170,6 @@ sgen_wait_for_suspend_ack (int count)
}
}
-gboolean
-sgen_park_current_thread_if_doing_handshake (SgenThreadInfo *p)
-{
- if (!p->doing_handshake)
- return FALSE;
-
- suspend_thread (p, NULL);
- return TRUE;
-}
-
int
sgen_thread_handshake (BOOL suspend)
{
@@ -222,9 +181,6 @@ sgen_thread_handshake (BOOL suspend)
count = 0;
FOREACH_THREAD_SAFE (info) {
- if (info->joined_stw == suspend)
- continue;
- info->joined_stw = suspend;
if (mono_native_thread_id_equals (mono_thread_info_get_tid (info), me)) {
continue;
}
@@ -232,13 +188,6 @@ sgen_thread_handshake (BOOL suspend)
continue;
/*if (signum == suspend_signal_num && info->stop_count == global_stop_count)
continue;*/
- if (suspend) {
- g_assert (!info->doing_handshake);
- info->doing_handshake = TRUE;
- } else {
- g_assert (info->doing_handshake);
- info->doing_handshake = FALSE;
- }
result = mono_threads_pthread_kill (info, signum);
if (result == 0) {
count++;
@@ -249,6 +198,8 @@ sgen_thread_handshake (BOOL suspend)
sgen_wait_for_suspend_ack (count);
+ SGEN_LOG (4, "%s handshake for %d threads\n", suspend ? "suspend" : "resume", count);
+
return count;
}
@@ -267,7 +218,7 @@ sgen_os_init (void)
g_error ("failed sigaction");
}
- sinfo.sa_handler = restart_handler;
+ sinfo.sa_handler = (void*) restart_handler;
if (sigaction (restart_signal_num, &sinfo, NULL) != 0) {
g_error ("failed sigaction");
}