#pragma textflag NOSPLITvoid(int32){// 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++;// Leave SP around for GC and traceback.savegetcallerpc(&),getcallersp));gsyscallsp=sched.sp;syscallpcpcsyscallstackstackbasesyscallguardstackguardstatusGsyscall;if<syscallguard-StackGuard||syscallsp// runtime·printf("entersyscall inconsistent %p [%p,%p]\n",161) !important; font-style: italic !important;">// g->syscallsp,g->syscallguard-StackGuard,g->syscallstack);·throw("entersyscall");}
mcachenil;pmstatusPsyscall);gcwaitingifstopwait>0&&casPgcstop{--==)stopnote}// Goroutines must not split stacks in Gsyscall status (it would corrupt g->sched).// We set stackguard to StackPreempt so that first split stack check calls morestack.// Morestack detects this case and throws.stackguard0StackPreempt--;这里提一个问题:为什么每次调用runtime·lock(&runtime.sched)及runtime·unlock(&runtime·sched)后,都要重新调用save保存SP和PC值呢?
*p;;// see comment in entersyscall"entersyscallblock"
后面的部分就不太一样了,基本上就是直接将当前M与P解耦,P重新回到Pidle状态。
p releasep();handoffpisbackground)// do not consider blocked scavenger for deadlock detectionincidlelocked(1);// Resave for traceback during blocked call.));// see comment in entersyscall前面说过,所有syscall包中的系统调用封装都只调用了runtime·entersyscall,那么runtime·entersyscallblock的使用场景是什么呢?
// The goroutine g exited its system call.// Arrange for it to run on a cpu again.// This is called only from the go syscall library,not// from the low-level system calls used by the runtime.@H_403_777@void// see comment in entersyscall-);exitsyscallfast())// There's a cpu for us,so we can run.syscalltickGrunning;// Garbage collector isn't running (since we are),161) !important; font-style: italic !important;">// so okay to clear gcstack and gcsp.=uintptr)preempt// restore the preemption request in case we've cleared it in newstack;}else// otherwise restore the real stackguard,we've spoiled it in entersyscall/entersyscallblock}return};
// Call the scheduler. mcallexitsyscall0// Scheduler returned,so we're allowed to run now.// Delete the gcstack information that we left for// the garbage collector during the system call.// Must wait until now because until gosched returns// we don't know for sure that the garbage collector// is not running.