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
This commit is contained in:
parent
09578bcd52
commit
4ea063cacb
|
@ -309,6 +309,8 @@ static void runtime_mcall(void (*)(G*)) __attribute__ ((noinline));
|
||||||
static void
|
static void
|
||||||
runtime_mcall(void (*pfn)(G*))
|
runtime_mcall(void (*pfn)(G*))
|
||||||
{
|
{
|
||||||
|
M *mp;
|
||||||
|
G *gp;
|
||||||
#ifndef USING_SPLIT_STACK
|
#ifndef USING_SPLIT_STACK
|
||||||
int i;
|
int i;
|
||||||
#endif
|
#endif
|
||||||
|
@ -317,28 +319,45 @@ runtime_mcall(void (*pfn)(G*))
|
||||||
// collector.
|
// collector.
|
||||||
__builtin_unwind_init();
|
__builtin_unwind_init();
|
||||||
|
|
||||||
if(g == m->g0)
|
mp = m;
|
||||||
|
gp = g;
|
||||||
|
if(gp == mp->g0)
|
||||||
runtime_throw("runtime: mcall called on m->g0 stack");
|
runtime_throw("runtime: mcall called on m->g0 stack");
|
||||||
|
|
||||||
if(g != nil) {
|
if(gp != nil) {
|
||||||
|
|
||||||
#ifdef USING_SPLIT_STACK
|
#ifdef USING_SPLIT_STACK
|
||||||
__splitstack_getcontext(&g->stack_context[0]);
|
__splitstack_getcontext(&g->stack_context[0]);
|
||||||
#else
|
#else
|
||||||
g->gcnext_sp = &i;
|
gp->gcnext_sp = &i;
|
||||||
#endif
|
#endif
|
||||||
g->fromgogo = false;
|
gp->fromgogo = false;
|
||||||
getcontext(&g->context);
|
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
|
#ifdef USING_SPLIT_STACK
|
||||||
__splitstack_setcontext(&m->g0->stack_context[0]);
|
__splitstack_setcontext(&mp->g0->stack_context[0]);
|
||||||
#endif
|
#endif
|
||||||
m->g0->entry = (byte*)pfn;
|
mp->g0->entry = (byte*)pfn;
|
||||||
m->g0->param = g;
|
mp->g0->param = gp;
|
||||||
g = m->g0;
|
|
||||||
fixcontext(&m->g0->context);
|
// It's OK to set g directly here because this case
|
||||||
setcontext(&m->g0->context);
|
// 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");
|
runtime_throw("runtime: mcall function returned");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue