diff options
-rw-r--r-- | libgo/runtime/proc.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c index 8f54e51..1bc0876 100644 --- a/libgo/runtime/proc.c +++ b/libgo/runtime/proc.c @@ -1857,10 +1857,30 @@ goexit0(G *gp) // entersyscall is going to return immediately after. void runtime_entersyscall(void) __attribute__ ((no_split_stack)); +static void doentersyscall(void) __attribute__ ((no_split_stack, noinline)); void runtime_entersyscall() { + // Save the registers in the g structure so that any pointers + // held in registers will be seen by the garbage collector. + getcontext(&g->gcregs); + + // Do the work in a separate function, so that this function + // doesn't save any registers on its own stack. If this + // function does save any registers, we might store the wrong + // value in the call to getcontext. + // + // FIXME: This assumes that we do not need to save any + // callee-saved registers to access the TLS variable g. We + // don't want to put the ucontext_t on the stack because it is + // large and we can not split the stack here. + doentersyscall(); +} + +static void +doentersyscall() +{ // Disable preemption because during this function g is in Gsyscall status, // but can have inconsistent g->sched, do not let GC observe it. m->locks++; @@ -1878,10 +1898,6 @@ runtime_entersyscall() } #endif - // Save the registers in the g structure so that any pointers - // held in registers will be seen by the garbage collector. - getcontext(&g->gcregs); - g->status = Gsyscall; if(runtime_atomicload(&runtime_sched.sysmonwait)) { // TODO: fast atomic |