1
0
mirror of https://github.com/golang/go synced 2024-11-17 00:14:50 -07:00

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:
Michael Anthony Knyszek 2023-05-10 20:36:08 +00:00 committed by Gopher Robot
parent c213c905a2
commit 2f35a655e7
2 changed files with 19 additions and 10 deletions

View File

@ -577,13 +577,17 @@ type m struct {
lockedExt uint32 // tracking for external LockOSThread
lockedInt uint32 // tracking for internal lockOSThread
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
waitlock unsafe.Pointer
waittraceev byte
waittraceskip int
startingtrace bool
syscalltick uint32
freelink *m // on sched.freem
syscalltick uint32
freelink *m // on sched.freem
trace mTraceState
// these are here because they are too large to be on the stack
// of low-level NOSPLIT functions.

View File

@ -169,6 +169,11 @@ type gTraceState struct {
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.
func traceLockInit() {
lockInit(&trace.bufLock, lockRankTraceBuf)
@ -252,10 +257,10 @@ func StartTrace() error {
// That would lead to an inconsistent trace:
// - either GoSysExit appears before EvGoInSyscall,
// - 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.
mp := getg().m
mp.startingtrace = true
mp.trace.startingTrace = true
// Obtain current stack ID to use in all traceEvGoCreate events below.
stkBuf := make([]uintptr, traceStackSize)
@ -324,7 +329,7 @@ func StartTrace() error {
trace.strings = make(map[string]uint64)
trace.seqGC = 0
mp.startingtrace = false
mp.trace.startingTrace = false
trace.enabled = true
// 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.
//
// Note trace_userTaskCreate runs the same check.
if !trace.enabled && !mp.startingtrace {
if !trace.enabled && !mp.trace.startingTrace {
traceReleaseBuffer(mp, pid)
return
}
@ -1642,7 +1647,7 @@ func trace_userTaskCreate(id, parentID uint64, taskType string) {
// Same as in traceEvent.
mp, pid, bufp := traceAcquireBuffer()
if !trace.enabled && !mp.startingtrace {
if !trace.enabled && !mp.trace.startingTrace {
traceReleaseBuffer(mp, pid)
return
}
@ -1664,7 +1669,7 @@ func trace_userRegion(id, mode uint64, name string) {
}
mp, pid, bufp := traceAcquireBuffer()
if !trace.enabled && !mp.startingtrace {
if !trace.enabled && !mp.trace.startingTrace {
traceReleaseBuffer(mp, pid)
return
}
@ -1681,7 +1686,7 @@ func trace_userLog(id uint64, category, message string) {
}
mp, pid, bufp := traceAcquireBuffer()
if !trace.enabled && !mp.startingtrace {
if !trace.enabled && !mp.trace.startingTrace {
traceReleaseBuffer(mp, pid)
return
}