mirror of https://github.com/golang/go.git
runtime: capture per-m trace state in a type
More tightening up of the tracer's interface. While we're here, clarify why waittraceskip isn't included by explaining what the wait* fields in the M are really for. Change-Id: I0e7b4cac79fb77a7a0b3ca6b6cc267668e3610bc Reviewed-on: https://go-review.googlesource.com/c/go/+/494190 Auto-Submit: Michael Knyszek <mknyszek@google.com> Run-TryBot: Michael Knyszek <mknyszek@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
c213c905a2
commit
2f35a655e7
|
|
@ -577,13 +577,17 @@ type m struct {
|
||||||
lockedExt uint32 // tracking for external LockOSThread
|
lockedExt uint32 // tracking for external LockOSThread
|
||||||
lockedInt uint32 // tracking for internal lockOSThread
|
lockedInt uint32 // tracking for internal lockOSThread
|
||||||
nextwaitm muintptr // next m waiting for lock
|
nextwaitm muintptr // next m waiting for lock
|
||||||
|
|
||||||
|
// wait* are used to carry arguments from gopark into park_m, because
|
||||||
|
// there's no stack to put them on. That is their sole purpose.
|
||||||
waitunlockf func(*g, unsafe.Pointer) bool
|
waitunlockf func(*g, unsafe.Pointer) bool
|
||||||
waitlock unsafe.Pointer
|
waitlock unsafe.Pointer
|
||||||
waittraceev byte
|
waittraceev byte
|
||||||
waittraceskip int
|
waittraceskip int
|
||||||
startingtrace bool
|
|
||||||
syscalltick uint32
|
syscalltick uint32
|
||||||
freelink *m // on sched.freem
|
freelink *m // on sched.freem
|
||||||
|
trace mTraceState
|
||||||
|
|
||||||
// these are here because they are too large to be on the stack
|
// these are here because they are too large to be on the stack
|
||||||
// of low-level NOSPLIT functions.
|
// of low-level NOSPLIT functions.
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,11 @@ type gTraceState struct {
|
||||||
lastP puintptr // last P emitted an event for this goroutine
|
lastP puintptr // last P emitted an event for this goroutine
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mTraceState is per-M state for the tracer.
|
||||||
|
type mTraceState struct {
|
||||||
|
startingTrace bool // this M is in TraceStart, potentially before traceEnabled is true
|
||||||
|
}
|
||||||
|
|
||||||
// traceLockInit initializes global trace locks.
|
// traceLockInit initializes global trace locks.
|
||||||
func traceLockInit() {
|
func traceLockInit() {
|
||||||
lockInit(&trace.bufLock, lockRankTraceBuf)
|
lockInit(&trace.bufLock, lockRankTraceBuf)
|
||||||
|
|
@ -252,10 +257,10 @@ func StartTrace() error {
|
||||||
// That would lead to an inconsistent trace:
|
// That would lead to an inconsistent trace:
|
||||||
// - either GoSysExit appears before EvGoInSyscall,
|
// - either GoSysExit appears before EvGoInSyscall,
|
||||||
// - or GoSysExit appears for a goroutine for which we don't emit EvGoInSyscall below.
|
// - or GoSysExit appears for a goroutine for which we don't emit EvGoInSyscall below.
|
||||||
// To instruct traceEvent that it must not ignore events below, we set startingtrace.
|
// To instruct traceEvent that it must not ignore events below, we set trace.startingTrace.
|
||||||
// trace.enabled is set afterwards once we have emitted all preliminary events.
|
// trace.enabled is set afterwards once we have emitted all preliminary events.
|
||||||
mp := getg().m
|
mp := getg().m
|
||||||
mp.startingtrace = true
|
mp.trace.startingTrace = true
|
||||||
|
|
||||||
// Obtain current stack ID to use in all traceEvGoCreate events below.
|
// Obtain current stack ID to use in all traceEvGoCreate events below.
|
||||||
stkBuf := make([]uintptr, traceStackSize)
|
stkBuf := make([]uintptr, traceStackSize)
|
||||||
|
|
@ -324,7 +329,7 @@ func StartTrace() error {
|
||||||
trace.strings = make(map[string]uint64)
|
trace.strings = make(map[string]uint64)
|
||||||
|
|
||||||
trace.seqGC = 0
|
trace.seqGC = 0
|
||||||
mp.startingtrace = false
|
mp.trace.startingTrace = false
|
||||||
trace.enabled = true
|
trace.enabled = true
|
||||||
|
|
||||||
// Register runtime goroutine labels.
|
// Register runtime goroutine labels.
|
||||||
|
|
@ -698,7 +703,7 @@ func traceEvent(ev byte, skip int, args ...uint64) {
|
||||||
// during tracing in exitsyscall is resolved by locking trace.bufLock in traceLockBuffer.
|
// during tracing in exitsyscall is resolved by locking trace.bufLock in traceLockBuffer.
|
||||||
//
|
//
|
||||||
// Note trace_userTaskCreate runs the same check.
|
// Note trace_userTaskCreate runs the same check.
|
||||||
if !trace.enabled && !mp.startingtrace {
|
if !trace.enabled && !mp.trace.startingTrace {
|
||||||
traceReleaseBuffer(mp, pid)
|
traceReleaseBuffer(mp, pid)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -1642,7 +1647,7 @@ func trace_userTaskCreate(id, parentID uint64, taskType string) {
|
||||||
|
|
||||||
// Same as in traceEvent.
|
// Same as in traceEvent.
|
||||||
mp, pid, bufp := traceAcquireBuffer()
|
mp, pid, bufp := traceAcquireBuffer()
|
||||||
if !trace.enabled && !mp.startingtrace {
|
if !trace.enabled && !mp.trace.startingTrace {
|
||||||
traceReleaseBuffer(mp, pid)
|
traceReleaseBuffer(mp, pid)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -1664,7 +1669,7 @@ func trace_userRegion(id, mode uint64, name string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mp, pid, bufp := traceAcquireBuffer()
|
mp, pid, bufp := traceAcquireBuffer()
|
||||||
if !trace.enabled && !mp.startingtrace {
|
if !trace.enabled && !mp.trace.startingTrace {
|
||||||
traceReleaseBuffer(mp, pid)
|
traceReleaseBuffer(mp, pid)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -1681,7 +1686,7 @@ func trace_userLog(id uint64, category, message string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mp, pid, bufp := traceAcquireBuffer()
|
mp, pid, bufp := traceAcquireBuffer()
|
||||||
if !trace.enabled && !mp.startingtrace {
|
if !trace.enabled && !mp.trace.startingTrace {
|
||||||
traceReleaseBuffer(mp, pid)
|
traceReleaseBuffer(mp, pid)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue