typedef struct _SgenClientThreadInfo SgenClientThreadInfo;
struct _SgenClientThreadInfo {
MonoThreadInfo info;
+
+ gpointer stopped_ip; /* only valid if the thread is stopped */
+ MonoDomain *stopped_domain; /* dsto */
};
#else
void sgen_client_pre_collection_checks (void);
+void sgen_client_thread_register (SgenThreadInfo* info, void *stack_bottom_fallback);
+
int sgen_client_stop_world (int generation);
int sgen_client_restart_world (int generation, GGTimingInfo *timing);
}
void*
-sgen_thread_register (SgenThreadInfo* info, void *addr)
+sgen_thread_register (SgenThreadInfo* info, void *stack_bottom_fallback)
{
size_t stsize = 0;
guint8 *staddr = NULL;
info->signal = 0;
#endif
info->skip = 0;
+ sgen_client_thread_register (info, stack_bottom_fallback);
info->stack_start = NULL;
- info->stopped_ip = NULL;
- info->stopped_domain = NULL;
#ifdef USE_MONO_CTX
memset (&info->ctx, 0, sizeof (MonoContext));
#else
#endif
info->stack_end = staddr + stsize;
} else {
- gsize stack_bottom = (gsize)addr;
+ gsize stack_bottom = (gsize)stack_bottom_fallback;
stack_bottom += 4095;
stack_bottom &= ~4095;
info->stack_end = (char*)stack_bottom;
unsigned int stop_count; /* to catch duplicate signals. */
#endif
- gpointer stopped_ip; /* only valid if the thread is stopped */
- MonoDomain *stopped_domain; /* dsto */
-
/*FIXME pretty please finish killing ARCH_NUM_REGS */
#ifdef USE_MONO_CTX
MonoContext ctx; /* ditto */
/* Could be called from sgen_thread_unregister () with a NULL info */
if (domain) {
g_assert (info);
- info->stopped_domain = domain;
+ info->client_info.stopped_domain = domain;
}
}
* Threads
*/
+void
+sgen_client_thread_register (SgenThreadInfo* info, void *stack_bottom_fallback)
+{
+ info->client_info.stopped_ip = NULL;
+ info->client_info.stopped_domain = NULL;
+}
+
static gboolean
is_critical_method (MonoMethod *method)
{
mono_mach_arch_thread_state_to_mcontext (state, mctx);
ctx.uc_mcontext = mctx;
- info->stopped_domain = mono_thread_info_tls_get (info, TLS_KEY_DOMAIN);
- info->stopped_ip = (gpointer) mono_mach_arch_get_ip (state);
+ info->client_info.stopped_domain = mono_thread_info_tls_get (info, TLS_KEY_DOMAIN);
+ info->client_info.stopped_ip = (gpointer) mono_mach_arch_get_ip (state);
info->stack_start = NULL;
stack_start = (char*) mono_mach_arch_get_sp (state) - REDZONE_SIZE;
/* If stack_start is not within the limits, then don't set it in info and we will be restarted. */
if (mono_gc_get_gc_callbacks ()->thread_suspend_func)
mono_gc_get_gc_callbacks ()->thread_suspend_func (info->runtime_data, &ctx, NULL);
- SGEN_LOG (2, "thread %p stopped at %p stack_start=%p", (void*)(gsize)info->client_info.info.native_handle, info->stopped_ip, info->stack_start);
-
- binary_protocol_thread_suspend ((gpointer)mono_thread_info_get_tid (info), info->stopped_ip);
+ SGEN_LOG (2, "thread %p stopped at %p stack_start=%p", (void*)(gsize)info->client_info.info.native_handle, info->client_info.stopped_ip, info->stack_start);
+ binary_protocol_thread_suspend ((gpointer)mono_thread_info_get_tid (info), info->client_info.stopped_ip);
return TRUE;
}
MonoContext ctx;
gpointer stack_start;
- info->stopped_domain = mono_domain_get ();
+ info->client_info.stopped_domain = mono_domain_get ();
info->signal = 0;
stop_count = sgen_global_stop_count;
/* duplicate signal */
#ifdef USE_MONO_CTX
if (context) {
mono_sigctx_to_monoctx (context, &ctx);
- info->stopped_ip = MONO_CONTEXT_GET_IP (&ctx);
+ info->client_info.stopped_ip = MONO_CONTEXT_GET_IP (&ctx);
stack_start = (((guint8 *) MONO_CONTEXT_GET_SP (&ctx)) - REDZONE_SIZE);
} else {
- info->stopped_ip = NULL;
+ info->client_info.stopped_ip = NULL;
stack_start = NULL;
}
#else
if (info->skip || info->gc_disabled || info->suspend_done)
continue;
if (mono_thread_info_is_live (info) && (!info->stack_start || info->in_critical_region || info->client_info.info.inside_critical_region ||
- is_ip_in_managed_allocator (info->stopped_domain, info->stopped_ip))) {
+ is_ip_in_managed_allocator (info->client_info.stopped_domain, info->client_info.stopped_ip))) {
binary_protocol_thread_restart ((gpointer)mono_thread_info_get_tid (info));
SGEN_LOG (3, "thread %p resumed.", (void*) (size_t) info->client_info.info.native_handle);
result = sgen_resume_thread (info);
we're not restarting so
that we can easily identify
the others */
- info->stopped_ip = NULL;
- info->stopped_domain = NULL;
+ info->client_info.stopped_ip = NULL;
+ info->client_info.stopped_domain = NULL;
info->suspend_done = TRUE;
}
} END_FOREACH_THREAD_SAFE
/* stop them again */
FOREACH_THREAD (info) {
gboolean result;
- if (info->skip || info->stopped_ip == NULL)
+ if (info->skip || info->client_info.stopped_ip == NULL)
continue;
result = sgen_suspend_thread (info);
char *stack_start;
/* Once we remove the old suspend code, we should move sgen to directly access the state in MonoThread */
- info->stopped_domain = mono_thread_info_tls_get (info, TLS_KEY_DOMAIN);
- info->stopped_ip = (gpointer) MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx);
+ info->client_info.stopped_domain = mono_thread_info_tls_get (info, TLS_KEY_DOMAIN);
+ info->client_info.stopped_ip = (gpointer) MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx);
stack_start = (char*)MONO_CONTEXT_GET_SP (&mono_thread_info_get_suspend_state (info)->ctx) - REDZONE_SIZE;
/* altstack signal handler, sgen can't handle them, mono-threads should have handled this. */