@@ -358,20 +358,20 @@ type g struct {
358358 atomicstatus uint32
359359 stackLock uint32 // sigprof/scang lock; TODO: fold in to atomicstatus
360360 goid int64
361- waitsince int64 // approx time when the g become blocked
362- waitreason string // if status==Gwaiting
363361 schedlink guintptr
364- preempt bool // preemption signal, duplicates stackguard0 = stackpreempt
365- paniconfault bool // panic (instead of crash) on unexpected fault address
366- preemptscan bool // preempted g does scan for gc
367- gcscandone bool // g has scanned stack; protected by _Gscan bit in status
368- gcscanvalid bool // false at start of gc cycle, true if G has not run since last scan; TODO: remove?
369- throwsplit bool // must not split stack
370- raceignore int8 // ignore race detection events
371- sysblocktraced bool // StartTrace has emitted EvGoInSyscall about this goroutine
372- sysexitticks int64 // cputicks when syscall has returned (for tracing)
373- traceseq uint64 // trace event sequencer
374- tracelastp puintptr // last P emitted an event for this goroutine
362+ waitsince int64 // approx time when the g become blocked
363+ waitreason waitReason // if status==Gwaiting
364+ preempt bool // preemption signal, duplicates stackguard0 = stackpreempt
365+ paniconfault bool // panic (instead of crash) on unexpected fault address
366+ preemptscan bool // preempted g does scan for gc
367+ gcscandone bool // g has scanned stack; protected by _Gscan bit in status
368+ gcscanvalid bool // false at start of gc cycle, true if G has not run since last scan; TODO: remove?
369+ throwsplit bool // must not split stack
370+ raceignore int8 // ignore race detection events
371+ sysblocktraced bool // StartTrace has emitted EvGoInSyscall about this goroutine
372+ sysexitticks int64 // cputicks when syscall has returned (for tracing)
373+ traceseq uint64 // trace event sequencer
374+ tracelastp puintptr // last P emitted an event for this goroutine
375375 lockedm muintptr
376376 sig uint32
377377 writebuf []byte
@@ -756,6 +756,71 @@ const (
756756// The maximum number of frames we print for a traceback
757757const _TracebackMaxFrames = 100
758758
759+ // A waitReason explains why a goroutine has been stopped.
760+ // See gopark. Do not re-use waitReasons, add new ones.
761+ type waitReason uint8
762+
763+ const (
764+ waitReasonZero waitReason = iota // ""
765+ waitReasonGCAssistMarking // "GC assist marking"
766+ waitReasonIOWait // "IO wait"
767+ waitReasonChanReceiveNilChan // "chan receive (nil chan)"
768+ waitReasonChanSendNilChan // "chan send (nil chan)"
769+ waitReasonDumpingHeap // "dumping heap"
770+ waitReasonGarbageCollection // "garbage collection"
771+ waitReasonGarbageCollectionScan // "garbage collection scan"
772+ waitReasonPanicWait // "panicwait"
773+ waitReasonSelect // "select"
774+ waitReasonSelectNoCases // "select (no cases)"
775+ waitReasonGCAssistWait // "GC assist wait"
776+ waitReasonGCSweepWait // "GC sweep wait"
777+ waitReasonChanReceive // "chan receive"
778+ waitReasonChanSend // "chan send"
779+ waitReasonFinalizerWait // "finalizer wait"
780+ waitReasonForceGGIdle // "force gc (idle)"
781+ waitReasonSemacquire // "semacquire"
782+ waitReasonSleep // "sleep"
783+ waitReasonSyncCondWait // "sync.Cond.Wait"
784+ waitReasonTimerGoroutineIdle // "timer goroutine (idle)"
785+ waitReasonTraceReaderBlocked // "trace reader (blocked)"
786+ waitReasonWaitForGCCycle // "wait for GC cycle"
787+ waitReasonGCWorkerIdle // "GC worker (idle)"
788+ )
789+
790+ var waitReasonStrings = [... ]string {
791+ waitReasonZero : "" ,
792+ waitReasonGCAssistMarking : "GC assist marking" ,
793+ waitReasonIOWait : "IO wait" ,
794+ waitReasonChanReceiveNilChan : "chan receive (nil chan)" ,
795+ waitReasonChanSendNilChan : "chan send (nil chan)" ,
796+ waitReasonDumpingHeap : "dumping heap" ,
797+ waitReasonGarbageCollection : "garbage collection" ,
798+ waitReasonGarbageCollectionScan : "garbage collection scan" ,
799+ waitReasonPanicWait : "panicwait" ,
800+ waitReasonSelect : "select" ,
801+ waitReasonSelectNoCases : "select (no cases)" ,
802+ waitReasonGCAssistWait : "GC assist wait" ,
803+ waitReasonGCSweepWait : "GC sweep wait" ,
804+ waitReasonChanReceive : "chan receive" ,
805+ waitReasonChanSend : "chan send" ,
806+ waitReasonFinalizerWait : "finalizer wait" ,
807+ waitReasonForceGGIdle : "force gc (idle)" ,
808+ waitReasonSemacquire : "semacquire" ,
809+ waitReasonSleep : "sleep" ,
810+ waitReasonSyncCondWait : "sync.Cond.Wait" ,
811+ waitReasonTimerGoroutineIdle : "timer goroutine (idle)" ,
812+ waitReasonTraceReaderBlocked : "trace reader (blocked)" ,
813+ waitReasonWaitForGCCycle : "wait for GC cycle" ,
814+ waitReasonGCWorkerIdle : "GC worker (idle)" ,
815+ }
816+
817+ func (w waitReason ) String () string {
818+ if w < 0 || w >= waitReason (len (waitReasonStrings )) {
819+ return "unknown wait reason"
820+ }
821+ return waitReasonStrings [w ]
822+ }
823+
759824var (
760825 allglen uintptr
761826 allm * m
0 commit comments