mirror of
https://github.com/encounter/bdwgc.git
synced 2026-03-30 10:57:55 -07:00
Handle pthread restart signals loss if retry_signals
Issue #181 (bdwgc). * doc/README.environment (GC_RETRY_SIGNALS, GC_NO_RETRY_SIGNALS): Update documentation (support of restart signals loss, try signals if compiled with ASan/MSan/TSan). * pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL] (GC_retry_signals): Set true also if ADDRESS_SANITIZER or MEMORY_SANITIZER. * pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL && !GC_NETBSD_THREADS_WORKAROUND] (GC_suspend_handler_inner): Call sem_post(GC_suspend_ack_sem) at the function end if GC_retry_signals; update comment about the RESTART signal loss. * pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL && !GC_OPENBSD_UTHREADS] (GC_start_world): Call resend_lost_signals(GC_restart_all) and update n_live_threads value. * pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL && !GC_OPENBSD_UTHREADS && !GC_NETBSD_THREADS_WORKAROUND] (GC_start_world): Call suspend_restart_barrier() if GC_retry_signals. * pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL] (GC_stop_init): Update the message logged if GC_retry_signals.
This commit is contained in:
@@ -97,11 +97,9 @@ GC_PRINT_BACK_HEIGHT - Print max length of chain through unreachable objects
|
||||
(http://www.hpl.hp.com/techreports/2001/HPL-2001-251.html).
|
||||
|
||||
GC_RETRY_SIGNALS, GC_NO_RETRY_SIGNALS - Try to compensate for lost
|
||||
thread suspend signals (Pthreads only). On by
|
||||
default for OSF1, off otherwise. Note
|
||||
that this does not work around a possible loss of
|
||||
thread restart signals. This seems to be necessary for
|
||||
some versions of Tru64. Since we've previously seen
|
||||
thread suspend and restart signals (Pthreads only).
|
||||
On by default for OSF1 (Tru64) or if the library is
|
||||
sanitized, off otherwise. Since we've previously seen
|
||||
similar issues on some other operating systems, it
|
||||
was turned into a runtime flag to enable last-minute
|
||||
work-arounds.
|
||||
|
||||
+21
-10
@@ -123,7 +123,8 @@ STATIC volatile AO_t GC_world_is_stopped = FALSE;
|
||||
/* before they are expected to stop (unless */
|
||||
/* they have stopped voluntarily). */
|
||||
|
||||
#if defined(GC_OSF1_THREADS) || defined(THREAD_SANITIZER)
|
||||
#if defined(GC_OSF1_THREADS) || defined(THREAD_SANITIZER) \
|
||||
|| defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER)
|
||||
STATIC GC_bool GC_retry_signals = TRUE;
|
||||
#else
|
||||
STATIC GC_bool GC_retry_signals = FALSE;
|
||||
@@ -362,18 +363,20 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy GC_ATTR_UNUSED,
|
||||
sigsuspend (&suspend_handler_mask);
|
||||
} while (AO_load_acquire(&GC_world_is_stopped)
|
||||
&& AO_load(&GC_stop_count) == my_stop_count);
|
||||
/* If the RESTART signal gets lost, we can still lose. That should */
|
||||
/* be less likely than losing the SUSPEND signal, since we don't do */
|
||||
/* much between the sem_post and sigsuspend. */
|
||||
/* We'd need more handshaking to work around that. */
|
||||
/* Simply dropping the sigsuspend call should be safe, but is */
|
||||
/* unlikely to be efficient. */
|
||||
|
||||
# ifdef DEBUG_THREADS
|
||||
GC_log_printf("Continuing %p\n", (void *)self);
|
||||
# endif
|
||||
# ifdef GC_NETBSD_THREADS_WORKAROUND
|
||||
sem_post(&GC_suspend_ack_sem);
|
||||
# else
|
||||
if (GC_retry_signals) {
|
||||
/* If the RESTART signal loss is possible (though it should be */
|
||||
/* less likely than losing the SUSPEND signal as we do not do */
|
||||
/* much between the sem_post and sigsuspend calls), more */
|
||||
/* handshaking is provided to work around it. */
|
||||
sem_post(&GC_suspend_ack_sem);
|
||||
}
|
||||
# endif
|
||||
RESTORE_CANCEL(cancel_state);
|
||||
}
|
||||
@@ -1107,8 +1110,15 @@ GC_INNER void GC_start_world(void)
|
||||
/* the list of functions which synchronize memory). */
|
||||
# endif
|
||||
n_live_threads = GC_restart_all();
|
||||
# if !defined(GC_OPENBSD_UTHREADS) && defined(GC_NETBSD_THREADS_WORKAROUND)
|
||||
suspend_restart_barrier(n_live_threads);
|
||||
# ifndef GC_OPENBSD_UTHREADS
|
||||
if (GC_retry_signals)
|
||||
n_live_threads = resend_lost_signals(n_live_threads, GC_restart_all);
|
||||
# ifdef GC_NETBSD_THREADS_WORKAROUND
|
||||
suspend_restart_barrier(n_live_threads);
|
||||
# else
|
||||
if (GC_retry_signals)
|
||||
suspend_restart_barrier(n_live_threads);
|
||||
# endif
|
||||
# else
|
||||
(void)n_live_threads;
|
||||
# endif
|
||||
@@ -1193,7 +1203,8 @@ GC_INNER void GC_stop_init(void)
|
||||
GC_retry_signals = FALSE;
|
||||
}
|
||||
if (GC_retry_signals) {
|
||||
GC_COND_LOG_PRINTF("Will retry suspend signal if necessary\n");
|
||||
GC_COND_LOG_PRINTF(
|
||||
"Will retry suspend and restart signals if necessary\n");
|
||||
}
|
||||
# ifndef NO_SIGNALS_UNBLOCK_IN_MAIN
|
||||
/* Explicitly unblock the signals once before new threads creation. */
|
||||
|
||||
Reference in New Issue
Block a user