mirror of https://github.com/golang/go.git
runtime: allow per-OS changes to unix profiler
Updates #35057 Change-Id: I56ea8f4750022847f0866c85e237a2cea40e0ff7 Reviewed-on: https://go-review.googlesource.com/c/go/+/342053 Run-TryBot: Rhys Hiltner <rhys@justin.tv> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Pratt <mpratt@google.com> Trust: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
parent
3d795ea798
commit
f9e90f7e74
|
|
@ -289,6 +289,19 @@ func sigdelset(mask *sigset, i int) {
|
|||
func (c *sigctxt) fixsigcode(sig uint32) {
|
||||
}
|
||||
|
||||
func setProcessCPUProfiler(hz int32) {
|
||||
setProcessCPUProfilerTimer(hz)
|
||||
}
|
||||
|
||||
func setThreadCPUProfiler(hz int32) {
|
||||
setThreadCPUProfilerHz(hz)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func validSIGPROF(mp *m, c *sigctxt) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func semacreate(mp *m) {
|
||||
if mp.waitsema != 0 {
|
||||
|
|
|
|||
|
|
@ -323,6 +323,19 @@ func sigdelset(mask *sigset, i int) {
|
|||
(*mask)[(i-1)/64] &^= 1 << ((uint32(i) - 1) & 63)
|
||||
}
|
||||
|
||||
func setProcessCPUProfiler(hz int32) {
|
||||
setProcessCPUProfilerTimer(hz)
|
||||
}
|
||||
|
||||
func setThreadCPUProfiler(hz int32) {
|
||||
setThreadCPUProfilerHz(hz)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func validSIGPROF(mp *m, c *sigctxt) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
const (
|
||||
_CLOCK_REALTIME = 9
|
||||
_CLOCK_MONOTONIC = 10
|
||||
|
|
|
|||
|
|
@ -425,6 +425,19 @@ func sigdelset(mask *sigset, i int) {
|
|||
*mask &^= 1 << (uint32(i) - 1)
|
||||
}
|
||||
|
||||
func setProcessCPUProfiler(hz int32) {
|
||||
setProcessCPUProfilerTimer(hz)
|
||||
}
|
||||
|
||||
func setThreadCPUProfiler(hz int32) {
|
||||
setThreadCPUProfilerHz(hz)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func validSIGPROF(mp *m, c *sigctxt) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
//go:linkname executablePath os.executablePath
|
||||
var executablePath string
|
||||
|
||||
|
|
|
|||
|
|
@ -268,6 +268,19 @@ func sigdelset(mask *sigset, i int) {
|
|||
func (c *sigctxt) fixsigcode(sig uint32) {
|
||||
}
|
||||
|
||||
func setProcessCPUProfiler(hz int32) {
|
||||
setProcessCPUProfilerTimer(hz)
|
||||
}
|
||||
|
||||
func setThreadCPUProfiler(hz int32) {
|
||||
setThreadCPUProfilerHz(hz)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func validSIGPROF(mp *m, c *sigctxt) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func sysargs(argc int32, argv **byte) {
|
||||
n := argc + 1
|
||||
|
||||
|
|
|
|||
|
|
@ -380,6 +380,19 @@ func sigdelset(mask *sigset, i int) {
|
|||
func (c *sigctxt) fixsigcode(sig uint32) {
|
||||
}
|
||||
|
||||
func setProcessCPUProfiler(hz int32) {
|
||||
setProcessCPUProfilerTimer(hz)
|
||||
}
|
||||
|
||||
func setThreadCPUProfiler(hz int32) {
|
||||
setThreadCPUProfilerHz(hz)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func validSIGPROF(mp *m, c *sigctxt) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func sysargs(argc int32, argv **byte) {
|
||||
n := argc + 1
|
||||
|
||||
|
|
|
|||
|
|
@ -517,3 +517,19 @@ func tgkill(tgid, tid, sig int)
|
|||
func signalM(mp *m, sig int) {
|
||||
tgkill(getpid(), int(mp.procid), sig)
|
||||
}
|
||||
|
||||
func setProcessCPUProfiler(hz int32) {
|
||||
setProcessCPUProfilerTimer(hz)
|
||||
}
|
||||
|
||||
func setThreadCPUProfiler(hz int32) {
|
||||
setThreadCPUProfilerHz(hz)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func validSIGPROF(mp *m, c *sigctxt) bool {
|
||||
// Once the profiler for Linux uses timer_create, this function will need to
|
||||
// do more than return true. But so long as the only profiling timer in use
|
||||
// is setitimer, returning true is correct.
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -371,6 +371,19 @@ func sigdelset(mask *sigset, i int) {
|
|||
func (c *sigctxt) fixsigcode(sig uint32) {
|
||||
}
|
||||
|
||||
func setProcessCPUProfiler(hz int32) {
|
||||
setProcessCPUProfilerTimer(hz)
|
||||
}
|
||||
|
||||
func setThreadCPUProfiler(hz int32) {
|
||||
setThreadCPUProfilerHz(hz)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func validSIGPROF(mp *m, c *sigctxt) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func sysargs(argc int32, argv **byte) {
|
||||
n := argc + 1
|
||||
|
||||
|
|
|
|||
|
|
@ -233,6 +233,19 @@ func sigdelset(mask *sigset, i int) {
|
|||
func (c *sigctxt) fixsigcode(sig uint32) {
|
||||
}
|
||||
|
||||
func setProcessCPUProfiler(hz int32) {
|
||||
setProcessCPUProfilerTimer(hz)
|
||||
}
|
||||
|
||||
func setThreadCPUProfiler(hz int32) {
|
||||
setThreadCPUProfilerHz(hz)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func validSIGPROF(mp *m, c *sigctxt) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
var haveMapStack = false
|
||||
|
||||
func osStackAlloc(s *mspan) {
|
||||
|
|
|
|||
|
|
@ -263,11 +263,11 @@ func clearSignalHandlers() {
|
|||
}
|
||||
}
|
||||
|
||||
// setProcessCPUProfiler is called when the profiling timer changes.
|
||||
// It is called with prof.lock held. hz is the new timer, and is 0 if
|
||||
// setProcessCPUProfilerTimer is called when the profiling timer changes.
|
||||
// It is called with prof.signalLock held. hz is the new timer, and is 0 if
|
||||
// profiling is being disabled. Enable or disable the signal as
|
||||
// required for -buildmode=c-archive.
|
||||
func setProcessCPUProfiler(hz int32) {
|
||||
func setProcessCPUProfilerTimer(hz int32) {
|
||||
if hz != 0 {
|
||||
// Enable the Go signal handler if not enabled.
|
||||
if atomic.Cas(&handlingSig[_SIGPROF], 0, 1) {
|
||||
|
|
@ -309,10 +309,10 @@ func setProcessCPUProfiler(hz int32) {
|
|||
}
|
||||
}
|
||||
|
||||
// setThreadCPUProfiler makes any thread-specific changes required to
|
||||
// setThreadCPUProfilerHz makes any thread-specific changes required to
|
||||
// implement profiling at a rate of hz.
|
||||
// No changes required on Unix systems.
|
||||
func setThreadCPUProfiler(hz int32) {
|
||||
// No changes required on Unix systems when using setitimer.
|
||||
func setThreadCPUProfilerHz(hz int32) {
|
||||
getg().m.profilehz = hz
|
||||
}
|
||||
|
||||
|
|
@ -423,7 +423,11 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
|
|||
setg(g)
|
||||
if g == nil {
|
||||
if sig == _SIGPROF {
|
||||
sigprofNonGoPC(c.sigpc())
|
||||
// Some platforms (Linux) have per-thread timers, which we use in
|
||||
// combination with the process-wide timer. Avoid double-counting.
|
||||
if validSIGPROF(nil, c) {
|
||||
sigprofNonGoPC(c.sigpc())
|
||||
}
|
||||
return
|
||||
}
|
||||
if sig == sigPreempt && preemptMSupported && debug.asyncpreemptoff == 0 {
|
||||
|
|
@ -540,7 +544,12 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
|
|||
c := &sigctxt{info, ctxt}
|
||||
|
||||
if sig == _SIGPROF {
|
||||
sigprof(c.sigpc(), c.sigsp(), c.siglr(), gp, _g_.m)
|
||||
mp := _g_.m
|
||||
// Some platforms (Linux) have per-thread timers, which we use in
|
||||
// combination with the process-wide timer. Avoid double-counting.
|
||||
if validSIGPROF(mp, c) {
|
||||
sigprof(c.sigpc(), c.sigsp(), c.siglr(), gp, mp)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue