Skip to content

Commit 195d133

Browse files
committed
change to emit create event in exitsyscall.
1 parent aaa997c commit 195d133

File tree

4 files changed

+55
-23
lines changed

4 files changed

+55
-23
lines changed

src/runtime/cgocall.go

+9
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ func cgocallbackg(fn, frame unsafe.Pointer, ctxt uintptr) {
227227
savedpc := gp.syscallpc
228228
exitsyscall() // coming out of cgo call
229229
gp.m.incgo = false
230+
if gp.m.isextra {
231+
gp.m.cgolevel++
232+
}
230233

231234
osPreemptExtExit(gp.m)
232235

@@ -237,6 +240,12 @@ func cgocallbackg(fn, frame unsafe.Pointer, ctxt uintptr) {
237240
// This is enforced by checking incgo in the schedule function.
238241

239242
gp.m.incgo = true
243+
if gp.m.isextra {
244+
gp.m.cgolevel--
245+
if gp.m.cgolevel < 0 {
246+
throw("unexpected negative cgolevel")
247+
}
248+
}
240249

241250
if gp.m != checkm {
242251
throw("m changed unexpectedly in cgocallbackg")

src/runtime/proc.go

+44-17
Original file line numberDiff line numberDiff line change
@@ -1917,11 +1917,6 @@ func oneNewExtraM() {
19171917
if raceenabled {
19181918
gp.racectx = racegostart(abi.FuncPCABIInternal(newextram) + sys.PCQuantum)
19191919
}
1920-
if trace.enabled {
1921-
traceGoCreate(gp, 0) // no start pc
1922-
gp.traceseq++
1923-
traceEvent(traceEvGoInSyscall, -1, uint64(gp.goid))
1924-
}
19251920
// put on allg for garbage collector
19261921
allgadd(gp)
19271922

@@ -2515,9 +2510,13 @@ func execute(gp *g, inheritTime bool) {
25152510
}
25162511

25172512
if trace.enabled {
2518-
// GoSysExit has to happen when we have a P, but before GoStart.
2519-
// So we emit it here.
2520-
if gp.syscallsp != 0 && gp.sysblocktraced {
2513+
if gp.m.isextra && gp.m.cgolevel == 0 {
2514+
// GoCreate happen in needm, but there is no P.
2515+
// So we emit it here.
2516+
traceGoCreate(gp, 0) // no start pc for locked g in extra M
2517+
} else if gp.syscallsp != 0 && gp.sysblocktraced {
2518+
// GoSysExit has to happen when we have a P, but before GoStart.
2519+
// So we emit it here.
25212520
traceGoSysExit(gp.sysexitticks)
25222521
}
25232522
traceGoStart()
@@ -3615,7 +3614,14 @@ func reentersyscall(pc, sp uintptr) {
36153614
}
36163615

36173616
if trace.enabled {
3618-
systemstack(traceGoSysCall)
3617+
if _g_.m.isextra && _g_.m.cgolevel == 0 {
3618+
systemstack(func() {
3619+
traceGoEnd()
3620+
traceProcStop(_g_.m.p.ptr())
3621+
})
3622+
} else {
3623+
systemstack(traceGoSysCall)
3624+
}
36193625
// systemstack itself clobbers g.sched.{pc,sp} and we might
36203626
// need them later when the G is genuinely blocked in a
36213627
// syscall
@@ -3639,10 +3645,19 @@ func reentersyscall(pc, sp uintptr) {
36393645
pp.m = 0
36403646
_g_.m.oldp.set(pp)
36413647
_g_.m.p = 0
3642-
atomic.Store(&pp.status, _Psyscall)
3643-
if sched.gcwaiting != 0 {
3644-
systemstack(entersyscall_gcwait)
3648+
3649+
if _g_.m.isextra && _g_.m.cgolevel == 0 {
3650+
atomic.Store(&pp.status, _Pidle)
3651+
systemstack(func() {
3652+
handoffp(pp)
3653+
})
36453654
save(pc, sp)
3655+
} else {
3656+
atomic.Store(&pp.status, _Psyscall)
3657+
if sched.gcwaiting != 0 {
3658+
systemstack(entersyscall_gcwait)
3659+
save(pc, sp)
3660+
}
36463661
}
36473662

36483663
_g_.m.locks--
@@ -3851,7 +3866,13 @@ func exitsyscallfast(oldp *p) bool {
38513866
osyield()
38523867
}
38533868
}
3854-
traceGoSysExit(0)
3869+
if _g_.m.isextra && _g_.m.cgolevel == 0 {
3870+
// GoCreate happen in needm, but there is no P.
3871+
// So we emit it here.
3872+
traceGoCreate(_g_, 0) // no start pc for locked g in extra M
3873+
} else {
3874+
traceGoSysExit(0)
3875+
}
38553876
}
38563877
})
38573878
if ok {
@@ -3874,10 +3895,16 @@ func exitsyscallfast_reacquired() {
38743895
// traceGoSysBlock for this syscall was already emitted,
38753896
// but here we effectively retake the p from the new syscall running on the same p.
38763897
systemstack(func() {
3877-
// Denote blocking of the new syscall.
3878-
traceGoSysBlock(_g_.m.p.ptr())
3879-
// Denote completion of the current syscall.
3880-
traceGoSysExit(0)
3898+
if _g_.m.isextra && _g_.m.cgolevel == 0 {
3899+
// GoCreate happen in needm, but there is no P.
3900+
// So we emit it here.
3901+
traceGoCreate(_g_, 0) // no start pc for locked g in extra M
3902+
} else {
3903+
// Denote blocking of the new syscall.
3904+
traceGoSysBlock(_g_.m.p.ptr())
3905+
// Denote completion of the current syscall.
3906+
traceGoSysExit(0)
3907+
}
38813908
})
38823909
}
38833910
_g_.m.p.ptr().syscalltick++

src/runtime/runtime2.go

+1
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,7 @@ type m struct {
540540
printlock int8
541541
incgo bool // m is executing a cgo call
542542
isextra bool // m is an extra m
543+
cgolevel int32 // level of cgo call
543544
freeWait uint32 // if == 0, safe to free g0 and delete m (atomic)
544545
fastrand uint64
545546
needextram bool

src/runtime/trace.go

+1-6
Original file line numberDiff line numberDiff line change
@@ -225,17 +225,12 @@ func StartTrace() error {
225225
// World is stopped, no need to lock.
226226
forEachGRace(func(gp *g) {
227227
status := readgstatus(gp)
228-
if status != _Gdead || (gp.m != nil && gp.m.isextra) {
228+
if status != _Gdead {
229229
gp.traceseq = 0
230230
gp.tracelastp = getg().m.p
231231
// +PCQuantum because traceFrameForPC expects return PCs and subtracts PCQuantum.
232232
id := trace.stackTab.put([]uintptr{startPCforTrace(gp.startpc) + sys.PCQuantum})
233233
traceEvent(traceEvGoCreate, -1, uint64(gp.goid), uint64(id), stackID)
234-
235-
if status == _Gdead {
236-
gp.traceseq++
237-
traceEvent(traceEvGoInSyscall, -1, uint64(gp.goid))
238-
}
239234
}
240235
if status == _Gwaiting {
241236
// traceEvGoWaiting is implied to have seq=1.

0 commit comments

Comments
 (0)