// src/runtime/runtime2.go
type g struct {
// 当前 goroutine 的栈内存范围
stack stack // offset known to runtime/cgo
stackguard0 uintptr// offset known to liblink
stackguard1 uintptr// offset known to liblink
_panic *_panic // g 中 panic 相关的处理
_defer *_defer // g 中 defer 相关的处理
m *m // 当前 g 绑定的 m
sched gobuf // 存储当前 g 调度相关的数据,上下文切换时会把当前信息保存到这里
// g 发生系统调用相关的参数
syscallsp uintptr// if status==Gsyscall, syscallsp = sched.sp to use during gc
syscallpc uintptr// if status==Gsyscall, syscallpc = sched.pc to use during gc
stktopsp uintptr// expected sp at top of stack, to check in traceback
// param is a generic pointer parameter field used to pass
// values in particular contexts where other storage for the
// parameter would be difficult to find. It is currently used
// in three ways:
// 1. When a channel operation wakes up a blocked goroutine, it sets param to
// point to the sudog of the completed blocking operation.
// 2. By gcAssistAlloc1 to signal back to its caller that the goroutine completed
// the GC cycle. It is unsafe to do so in any other way, because the goroutine's
// stack may have moved in the meantime.
// 3. By debugCallWrap to pass parameters to a new goroutine because allocating a
// closure in the runtime is forbidden.
param unsafe.Pointer
atomicstatus atomic.Uint32 // g 的状态
stackLock uint32// sigprof/scang lock; TODO: fold in to atomicstatus
goid uint64// g 的 id
......}