mirror of https://github.com/golang/go.git
runtime: fix, simplify, and improve scan state in goroutine header
Currently goroutineheader goes through some convolutions to *almost* print the scan state of a G. However, the code path that would print the scan state of the G refers to gStatusStrings where it almost certainly meant to refer to gScanStatusStrings (which is unused), so it winds up printing the regular status string without the scan state either way. Furthermore, if the G is in _Gwaiting, we override the status string and lose where this would indicate the scan state if it worked. This commit fixes this so the runtime prints the scan state. However, rather than using a parallel list of status strings, this simply adds a conditional print if the scan bit is set. This lets us remove the string list, prints the scan state even in _Gwaiting, and lets us strip off the scan bit at the beginning of the function, which simplifies the rest of it. Change-Id: Ic0adbe5c05abf4adda93da59f93b578172b28e3d Reviewed-on: https://go-review.googlesource.com/18092 Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
0f3c229030
commit
c7c7c7031d
|
|
@ -645,41 +645,34 @@ var gStatusStrings = [...]string{
|
|||
_Gcopystack: "copystack",
|
||||
}
|
||||
|
||||
var gScanStatusStrings = [...]string{
|
||||
0: "scan",
|
||||
_Grunnable: "scanrunnable",
|
||||
_Grunning: "scanrunning",
|
||||
_Gsyscall: "scansyscall",
|
||||
_Gwaiting: "scanwaiting",
|
||||
_Gdead: "scandead",
|
||||
_Genqueue: "scanenqueue",
|
||||
}
|
||||
|
||||
func goroutineheader(gp *g) {
|
||||
gpstatus := readgstatus(gp)
|
||||
|
||||
isScan := gpstatus&_Gscan != 0
|
||||
gpstatus &^= _Gscan // drop the scan bit
|
||||
|
||||
// Basic string status
|
||||
var status string
|
||||
if 0 <= gpstatus && gpstatus < uint32(len(gStatusStrings)) {
|
||||
status = gStatusStrings[gpstatus]
|
||||
} else if gpstatus&_Gscan != 0 && 0 <= gpstatus&^_Gscan && gpstatus&^_Gscan < uint32(len(gStatusStrings)) {
|
||||
status = gStatusStrings[gpstatus&^_Gscan]
|
||||
} else {
|
||||
status = "???"
|
||||
}
|
||||
|
||||
// Override.
|
||||
if (gpstatus == _Gwaiting || gpstatus == _Gscanwaiting) && gp.waitreason != "" {
|
||||
if gpstatus == _Gwaiting && gp.waitreason != "" {
|
||||
status = gp.waitreason
|
||||
}
|
||||
|
||||
// approx time the G is blocked, in minutes
|
||||
var waitfor int64
|
||||
gpstatus &^= _Gscan // drop the scan bit
|
||||
if (gpstatus == _Gwaiting || gpstatus == _Gsyscall) && gp.waitsince != 0 {
|
||||
waitfor = (nanotime() - gp.waitsince) / 60e9
|
||||
}
|
||||
print("goroutine ", gp.goid, " [", status)
|
||||
if isScan {
|
||||
print(" (scan)")
|
||||
}
|
||||
if waitfor >= 1 {
|
||||
print(", ", waitfor, " minutes")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue