aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/runtime/signal_unix.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/runtime/signal_unix.go')
-rw-r--r--libgo/go/runtime/signal_unix.go68
1 files changed, 39 insertions, 29 deletions
diff --git a/libgo/go/runtime/signal_unix.go b/libgo/go/runtime/signal_unix.go
index ec7c647..1c040f7 100644
--- a/libgo/go/runtime/signal_unix.go
+++ b/libgo/go/runtime/signal_unix.go
@@ -281,6 +281,12 @@ func setProcessCPUProfiler(hz int32) {
atomic.Storeuintptr(&fwdSig[_SIGPROF], getsig(_SIGPROF))
setsig(_SIGPROF, getSigtramp())
}
+
+ var it _itimerval
+ it.it_interval.tv_sec = 0
+ it.it_interval.set_usec(1000000 / hz)
+ it.it_value = it.it_interval
+ setitimer(_ITIMER_PROF, &it, nil)
} else {
// If the Go signal handler should be disabled by default,
// switch back to the signal handler that was installed
@@ -305,23 +311,16 @@ func setProcessCPUProfiler(hz int32) {
setsig(_SIGPROF, h)
}
}
+
+ setitimer(_ITIMER_PROF, &_itimerval{}, nil)
}
}
// setThreadCPUProfiler makes any thread-specific changes required to
// implement profiling at a rate of hz.
+// No changes required on Unix systems.
func setThreadCPUProfiler(hz int32) {
- var it _itimerval
- if hz == 0 {
- setitimer(_ITIMER_PROF, &it, nil)
- } else {
- it.it_interval.tv_sec = 0
- it.it_interval.set_usec(1000000 / hz)
- it.it_value = it.it_interval
- setitimer(_ITIMER_PROF, &it, nil)
- }
- _g_ := getg()
- _g_.m.profilehz = hz
+ getg().m.profilehz = hz
}
func sigpipe() {
@@ -348,7 +347,7 @@ func doSigPreempt(gp *g, ctxt *sigctxt, sigpc uintptr) {
atomic.Xadd(&gp.m.preemptGen, 1)
atomic.Store(&gp.m.signalPending, 0)
- if GOOS == "darwin" {
+ if GOOS == "darwin" || GOOS == "ios" {
atomic.Xadd(&pendingPreemptSignals, -1)
}
}
@@ -363,18 +362,29 @@ const preemptMSupported = false
// safe-point, it will preempt the goroutine. It always atomically
// increments mp.preemptGen after handling a preemption request.
func preemptM(mp *m) {
- if GOOS == "darwin" && GOARCH == "arm64" && !iscgo {
- // On darwin, we use libc calls, and cgo is required on ARM64
- // so we have TLS set up to save/restore G during C calls. If cgo is
- // absent, we cannot save/restore G in TLS, and if a signal is
- // received during C execution we cannot get the G. Therefore don't
- // send signals.
- // This can only happen in the go_bootstrap program (otherwise cgo is
- // required).
- return
+ // On Darwin, don't try to preempt threads during exec.
+ // Issue #41702.
+ if GOOS == "darwin" || GOOS == "ios" {
+ execLock.rlock()
+ }
+
+ if atomic.Cas(&mp.signalPending, 0, 1) {
+ if GOOS == "darwin" || GOOS == "ios" {
+ atomic.Xadd(&pendingPreemptSignals, 1)
+ }
+
+ // If multiple threads are preempting the same M, it may send many
+ // signals to the same M such that it hardly make progress, causing
+ // live-lock problem. Apparently this could happen on darwin. See
+ // issue #37741.
+ // Only send a signal if there isn't already one pending.
+ // signalM(mp, sigPreempt)
+ throw("signalM not implemented")
+ }
+
+ if GOOS == "darwin" || GOOS == "ios" {
+ execLock.runlock()
}
- // signalM(mp, sigPreempt)
- throw("signalM not implemented")
}
// sigtrampgo is called from the signal handler function, sigtramp,
@@ -408,7 +418,7 @@ func sigtrampgo(sig uint32, info *_siginfo_t, ctx unsafe.Pointer) {
// no non-Go signal handler for sigPreempt.
// The default behavior for sigPreempt is to ignore
// the signal, so badsignal will be a no-op anyway.
- if GOOS == "darwin" {
+ if GOOS == "darwin" || GOOS == "ios" {
atomic.Xadd(&pendingPreemptSignals, -1)
}
return
@@ -565,7 +575,7 @@ func sighandler(sig uint32, info *_siginfo_t, ctxt unsafe.Pointer, gp *g) {
print("signal arrived during cgo execution\n")
gp = _g_.m.lockedg.ptr()
}
- if sig == _SIGILL {
+ if sig == _SIGILL || sig == _SIGFPE {
// It would be nice to know how long the instruction is.
// Unfortunately, that's complicated to do in general (mostly for x86
// and s930x, but other archs have non-standard instruction lengths also).
@@ -656,7 +666,7 @@ func sigpanic() {
}
// Support runtime/debug.SetPanicOnFault.
if g.paniconfault {
- panicmem()
+ panicmemAddr(g.sigcode1)
}
print("unexpected fault address ", hex(g.sigcode1), "\n")
throw("fault")
@@ -666,7 +676,7 @@ func sigpanic() {
}
// Support runtime/debug.SetPanicOnFault.
if g.paniconfault {
- panicmem()
+ panicmemAddr(g.sigcode1)
}
print("unexpected fault address ", hex(g.sigcode1), "\n")
throw("fault")
@@ -879,7 +889,7 @@ func badsignal(sig uintptr, c *sigctxt) {
exit(2)
*(*uintptr)(unsafe.Pointer(uintptr(123))) = 2
}
- needm(0)
+ needm()
if !sigsend(uint32(sig)) {
// A foreign thread received the signal sig, and the
// Go code does not want to handle it.
@@ -922,7 +932,7 @@ func sigfwdgo(sig uint32, info *_siginfo_t, ctx unsafe.Pointer) bool {
// This function and its caller sigtrampgo assumes SIGPIPE is delivered on the
// originating thread. This property does not hold on macOS (golang.org/issue/33384),
// so we have no choice but to ignore SIGPIPE.
- if GOOS == "darwin" && sig == _SIGPIPE {
+ if (GOOS == "darwin" || GOOS == "ios") && sig == _SIGPIPE {
return true
}