mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: refactor runtime->tracer API to appear more like a lock
Currently the execution tracer synchronizes with itself using very
heavyweight operations. As a result, it's totally fine for most of the
tracer code to look like:
if traceEnabled() {
traceXXX(...)
}
However, if we want to make that synchronization more lightweight (as
issue #60773 proposes), then this is insufficient. In particular, we
need to make sure the tracer can't observe an inconsistency between g
atomicstatus and the event that would be emitted for a particular
g transition. This means making the g status change appear to happen
atomically with the corresponding trace event being written out from the
perspective of the tracer.
This requires a change in API to something more like a lock. While we're
here, we might as well make sure that trace events can *only* be emitted
while this lock is held. This change introduces such an API:
traceAcquire, which returns a value that can emit events, and
traceRelease, which requires the value that was returned by
traceAcquire. In practice, this won't be a real lock, it'll be more like
a seqlock.
For the current tracer, this API is completely overkill and the value
returned by traceAcquire basically just checks trace.enabled. But it's
necessary for the tracer described in #60773 and we can implement that
more cleanly if we do this refactoring now instead of later.
For #60773.
Change-Id: Ibb9ff5958376339fafc2b5180aef65cf2ba18646
Reviewed-on: https://go-review.googlesource.com/c/go/+/515635
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
This commit is contained in:
parent
e3585c6757
commit
f119abb65d
9 changed files with 388 additions and 177 deletions
|
|
@ -791,8 +791,10 @@ func (h *mheap) reclaim(npage uintptr) {
|
|||
// traceGCSweepStart/Done pair on the P.
|
||||
mp := acquirem()
|
||||
|
||||
if traceEnabled() {
|
||||
traceGCSweepStart()
|
||||
trace := traceAcquire()
|
||||
if trace.ok() {
|
||||
trace.GCSweepStart()
|
||||
traceRelease(trace)
|
||||
}
|
||||
|
||||
arenas := h.sweepArenas
|
||||
|
|
@ -839,8 +841,10 @@ func (h *mheap) reclaim(npage uintptr) {
|
|||
unlock(&h.lock)
|
||||
}
|
||||
|
||||
if traceEnabled() {
|
||||
traceGCSweepDone()
|
||||
trace = traceAcquire()
|
||||
if trace.ok() {
|
||||
trace.GCSweepDone()
|
||||
traceRelease(trace)
|
||||
}
|
||||
releasem(mp)
|
||||
}
|
||||
|
|
@ -911,10 +915,12 @@ func (h *mheap) reclaimChunk(arenas []arenaIdx, pageIdx, n uintptr) uintptr {
|
|||
n -= uintptr(len(inUse) * 8)
|
||||
}
|
||||
sweep.active.end(sl)
|
||||
if traceEnabled() {
|
||||
trace := traceAcquire()
|
||||
if trace.ok() {
|
||||
unlock(&h.lock)
|
||||
// Account for pages scanned but not reclaimed.
|
||||
traceGCSweepSpan((n0 - nFreed) * pageSize)
|
||||
trace.GCSweepSpan((n0 - nFreed) * pageSize)
|
||||
traceRelease(trace)
|
||||
lock(&h.lock)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue