Skip to content

Commit f9e90f7

Browse files
rhyshprattmic
authored andcommitted
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 <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Michael Pratt <[email protected]> Trust: Michael Knyszek <[email protected]>
1 parent 3d795ea commit f9e90f7

9 files changed

+124
-8
lines changed

src/runtime/os3_solaris.go

+13
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,19 @@ func sigdelset(mask *sigset, i int) {
289289
func (c *sigctxt) fixsigcode(sig uint32) {
290290
}
291291

292+
func setProcessCPUProfiler(hz int32) {
293+
setProcessCPUProfilerTimer(hz)
294+
}
295+
296+
func setThreadCPUProfiler(hz int32) {
297+
setThreadCPUProfilerHz(hz)
298+
}
299+
300+
//go:nosplit
301+
func validSIGPROF(mp *m, c *sigctxt) bool {
302+
return true
303+
}
304+
292305
//go:nosplit
293306
func semacreate(mp *m) {
294307
if mp.waitsema != 0 {

src/runtime/os_aix.go

+13
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,19 @@ func sigdelset(mask *sigset, i int) {
323323
(*mask)[(i-1)/64] &^= 1 << ((uint32(i) - 1) & 63)
324324
}
325325

326+
func setProcessCPUProfiler(hz int32) {
327+
setProcessCPUProfilerTimer(hz)
328+
}
329+
330+
func setThreadCPUProfiler(hz int32) {
331+
setThreadCPUProfilerHz(hz)
332+
}
333+
334+
//go:nosplit
335+
func validSIGPROF(mp *m, c *sigctxt) bool {
336+
return true
337+
}
338+
326339
const (
327340
_CLOCK_REALTIME = 9
328341
_CLOCK_MONOTONIC = 10

src/runtime/os_darwin.go

+13
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,19 @@ func sigdelset(mask *sigset, i int) {
425425
*mask &^= 1 << (uint32(i) - 1)
426426
}
427427

428+
func setProcessCPUProfiler(hz int32) {
429+
setProcessCPUProfilerTimer(hz)
430+
}
431+
432+
func setThreadCPUProfiler(hz int32) {
433+
setThreadCPUProfilerHz(hz)
434+
}
435+
436+
//go:nosplit
437+
func validSIGPROF(mp *m, c *sigctxt) bool {
438+
return true
439+
}
440+
428441
//go:linkname executablePath os.executablePath
429442
var executablePath string
430443

src/runtime/os_dragonfly.go

+13
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,19 @@ func sigdelset(mask *sigset, i int) {
268268
func (c *sigctxt) fixsigcode(sig uint32) {
269269
}
270270

271+
func setProcessCPUProfiler(hz int32) {
272+
setProcessCPUProfilerTimer(hz)
273+
}
274+
275+
func setThreadCPUProfiler(hz int32) {
276+
setThreadCPUProfilerHz(hz)
277+
}
278+
279+
//go:nosplit
280+
func validSIGPROF(mp *m, c *sigctxt) bool {
281+
return true
282+
}
283+
271284
func sysargs(argc int32, argv **byte) {
272285
n := argc + 1
273286

src/runtime/os_freebsd.go

+13
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,19 @@ func sigdelset(mask *sigset, i int) {
380380
func (c *sigctxt) fixsigcode(sig uint32) {
381381
}
382382

383+
func setProcessCPUProfiler(hz int32) {
384+
setProcessCPUProfilerTimer(hz)
385+
}
386+
387+
func setThreadCPUProfiler(hz int32) {
388+
setThreadCPUProfilerHz(hz)
389+
}
390+
391+
//go:nosplit
392+
func validSIGPROF(mp *m, c *sigctxt) bool {
393+
return true
394+
}
395+
383396
func sysargs(argc int32, argv **byte) {
384397
n := argc + 1
385398

src/runtime/os_linux.go

+16
Original file line numberDiff line numberDiff line change
@@ -517,3 +517,19 @@ func tgkill(tgid, tid, sig int)
517517
func signalM(mp *m, sig int) {
518518
tgkill(getpid(), int(mp.procid), sig)
519519
}
520+
521+
func setProcessCPUProfiler(hz int32) {
522+
setProcessCPUProfilerTimer(hz)
523+
}
524+
525+
func setThreadCPUProfiler(hz int32) {
526+
setThreadCPUProfilerHz(hz)
527+
}
528+
529+
//go:nosplit
530+
func validSIGPROF(mp *m, c *sigctxt) bool {
531+
// Once the profiler for Linux uses timer_create, this function will need to
532+
// do more than return true. But so long as the only profiling timer in use
533+
// is setitimer, returning true is correct.
534+
return true
535+
}

src/runtime/os_netbsd.go

+13
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,19 @@ func sigdelset(mask *sigset, i int) {
371371
func (c *sigctxt) fixsigcode(sig uint32) {
372372
}
373373

374+
func setProcessCPUProfiler(hz int32) {
375+
setProcessCPUProfilerTimer(hz)
376+
}
377+
378+
func setThreadCPUProfiler(hz int32) {
379+
setThreadCPUProfilerHz(hz)
380+
}
381+
382+
//go:nosplit
383+
func validSIGPROF(mp *m, c *sigctxt) bool {
384+
return true
385+
}
386+
374387
func sysargs(argc int32, argv **byte) {
375388
n := argc + 1
376389

src/runtime/os_openbsd.go

+13
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,19 @@ func sigdelset(mask *sigset, i int) {
233233
func (c *sigctxt) fixsigcode(sig uint32) {
234234
}
235235

236+
func setProcessCPUProfiler(hz int32) {
237+
setProcessCPUProfilerTimer(hz)
238+
}
239+
240+
func setThreadCPUProfiler(hz int32) {
241+
setThreadCPUProfilerHz(hz)
242+
}
243+
244+
//go:nosplit
245+
func validSIGPROF(mp *m, c *sigctxt) bool {
246+
return true
247+
}
248+
236249
var haveMapStack = false
237250

238251
func osStackAlloc(s *mspan) {

src/runtime/signal_unix.go

+17-8
Original file line numberDiff line numberDiff line change
@@ -263,11 +263,11 @@ func clearSignalHandlers() {
263263
}
264264
}
265265

266-
// setProcessCPUProfiler is called when the profiling timer changes.
267-
// It is called with prof.lock held. hz is the new timer, and is 0 if
266+
// setProcessCPUProfilerTimer is called when the profiling timer changes.
267+
// It is called with prof.signalLock held. hz is the new timer, and is 0 if
268268
// profiling is being disabled. Enable or disable the signal as
269269
// required for -buildmode=c-archive.
270-
func setProcessCPUProfiler(hz int32) {
270+
func setProcessCPUProfilerTimer(hz int32) {
271271
if hz != 0 {
272272
// Enable the Go signal handler if not enabled.
273273
if atomic.Cas(&handlingSig[_SIGPROF], 0, 1) {
@@ -309,10 +309,10 @@ func setProcessCPUProfiler(hz int32) {
309309
}
310310
}
311311

312-
// setThreadCPUProfiler makes any thread-specific changes required to
312+
// setThreadCPUProfilerHz makes any thread-specific changes required to
313313
// implement profiling at a rate of hz.
314-
// No changes required on Unix systems.
315-
func setThreadCPUProfiler(hz int32) {
314+
// No changes required on Unix systems when using setitimer.
315+
func setThreadCPUProfilerHz(hz int32) {
316316
getg().m.profilehz = hz
317317
}
318318

@@ -423,7 +423,11 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
423423
setg(g)
424424
if g == nil {
425425
if sig == _SIGPROF {
426-
sigprofNonGoPC(c.sigpc())
426+
// Some platforms (Linux) have per-thread timers, which we use in
427+
// combination with the process-wide timer. Avoid double-counting.
428+
if validSIGPROF(nil, c) {
429+
sigprofNonGoPC(c.sigpc())
430+
}
427431
return
428432
}
429433
if sig == sigPreempt && preemptMSupported && debug.asyncpreemptoff == 0 {
@@ -540,7 +544,12 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
540544
c := &sigctxt{info, ctxt}
541545

542546
if sig == _SIGPROF {
543-
sigprof(c.sigpc(), c.sigsp(), c.siglr(), gp, _g_.m)
547+
mp := _g_.m
548+
// Some platforms (Linux) have per-thread timers, which we use in
549+
// combination with the process-wide timer. Avoid double-counting.
550+
if validSIGPROF(mp, c) {
551+
sigprof(c.sigpc(), c.sigsp(), c.siglr(), gp, mp)
552+
}
544553
return
545554
}
546555

0 commit comments

Comments
 (0)