From 4ea063cacb9088c9a1bb9980d3850a6af8b83a5d Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 14 Feb 2012 00:38:07 +0000 Subject: [PATCH] re PR go/50654 (Many Go tests fail on emutls targets) PR go/50654 runtime: Reload m and g if necessary after getcontext returns. From-SVN: r184188 --- libgo/runtime/proc.c | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c index 94c2a51..609920a 100644 --- a/libgo/runtime/proc.c +++ b/libgo/runtime/proc.c @@ -309,6 +309,8 @@ static void runtime_mcall(void (*)(G*)) __attribute__ ((noinline)); static void runtime_mcall(void (*pfn)(G*)) { + M *mp; + G *gp; #ifndef USING_SPLIT_STACK int i; #endif @@ -317,28 +319,45 @@ runtime_mcall(void (*pfn)(G*)) // collector. __builtin_unwind_init(); - if(g == m->g0) + mp = m; + gp = g; + if(gp == mp->g0) runtime_throw("runtime: mcall called on m->g0 stack"); - if(g != nil) { + if(gp != nil) { #ifdef USING_SPLIT_STACK __splitstack_getcontext(&g->stack_context[0]); #else - g->gcnext_sp = &i; + gp->gcnext_sp = &i; #endif - g->fromgogo = false; - getcontext(&g->context); + gp->fromgogo = false; + getcontext(&gp->context); + + // When we return from getcontext, we may be running + // in a new thread. That means that m and g may have + // changed. They are global variables so we will + // reload them, but the addresses of m and g may be + // cached in our local stack frame, and those + // addresses may be wrong. Call functions to reload + // the values for this thread. + mp = runtime_m(); + gp = runtime_g(); } - if (g == nil || !g->fromgogo) { + if (gp == nil || !gp->fromgogo) { #ifdef USING_SPLIT_STACK - __splitstack_setcontext(&m->g0->stack_context[0]); + __splitstack_setcontext(&mp->g0->stack_context[0]); #endif - m->g0->entry = (byte*)pfn; - m->g0->param = g; - g = m->g0; - fixcontext(&m->g0->context); - setcontext(&m->g0->context); + mp->g0->entry = (byte*)pfn; + mp->g0->param = gp; + + // It's OK to set g directly here because this case + // can not occur if we got here via a setcontext to + // the getcontext call just above. + g = mp->g0; + + fixcontext(&mp->g0->context); + setcontext(&mp->g0->context); runtime_throw("runtime: mcall function returned"); } } -- 2.7.4