// 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()
{
if(m->profilehz > 0)
runtime_setprof(false);
}
#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