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
1 changed files with 31 additions and 12 deletions
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue