From: Elias Naur Date: Tue, 17 Nov 2015 10:41:06 +0000 (+0100) Subject: runtime: use a proper type, sigset, for m.sigmask X-Git-Tag: go1.6beta1~413 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=7db77271e423604c3b58b4c4da60ddc3c3eecc0d;p=gostls13.git runtime: use a proper type, sigset, for m.sigmask Replace the cross platform but unsafe [4]uintptr type with a OS specific type, sigset. Most OSes already define sigset, and this change defines a suitable sigset for the OSes that don't (darwin, openbsd). The OSes that don't use m.sigmask (windows, plan9, nacl) now defines sigset as the empty type, struct{}. The gain is strongly typed access to m.sigmask, saving a dynamic size sanity check and unsafe.Pointer casting. Also, some storage is saved for each M, since [4]uinptr was conservative for most OSes. The cost is that OSes that don't need m.sigmask has to define sigset. completes ./all.bash with GOOS linux, on amd64 completes ./make.bash with GOOSes openbsd, android, plan9, windows, darwin, solaris, netbsd, freebsd, dragonfly, all amd64. With GOOS=nacl ./make.bash failed with a seemingly unrelated error. R=go1.7 Change-Id: Ib460379f063eb83d393e1c5efe7333a643c1595e Reviewed-on: https://go-review.googlesource.com/16942 Reviewed-by: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot --- diff --git a/src/runtime/os1_darwin.go b/src/runtime/os1_darwin.go index ba38a78ed1..e702739508 100644 --- a/src/runtime/os1_darwin.go +++ b/src/runtime/os1_darwin.go @@ -8,7 +8,9 @@ import "unsafe" //extern SigTabTT runtime·sigtab[]; -var sigset_all = ^uint32(0) +type sigset uint32 + +var sigset_all = ^sigset(0) func unimplemented(name string) { println(name, "not implemented") @@ -83,7 +85,7 @@ func newosproc(mp *m, stk unsafe.Pointer) { print("newosproc stk=", stk, " m=", mp, " g=", mp.g0, " id=", mp.id, " ostk=", &mp, "\n") } - var oset uint32 + var oset sigset sigprocmask(_SIG_SETMASK, &sigset_all, &oset) errno := bsdthread_create(stk, unsafe.Pointer(mp), funcPC(mstart)) sigprocmask(_SIG_SETMASK, &oset, nil) @@ -109,7 +111,7 @@ func newosproc0(stacksize uintptr, fn unsafe.Pointer, fnarg uintptr) { } stk := unsafe.Pointer(uintptr(stack) + stacksize) - var oset uint32 + var oset sigset sigprocmask(_SIG_SETMASK, &sigset_all, &oset) errno := bsdthread_create(stk, fn, fnarg) sigprocmask(_SIG_SETMASK, &oset, nil) @@ -131,11 +133,7 @@ func mpreinit(mp *m) { } func msigsave(mp *m) { - smask := (*uint32)(unsafe.Pointer(&mp.sigmask)) - if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) { - throw("insufficient storage for signal mask") - } - sigprocmask(_SIG_SETMASK, nil, smask) + sigprocmask(_SIG_SETMASK, nil, &mp.sigmask) } // Called to initialize a new m (including the bootstrap m). @@ -146,7 +144,7 @@ func minit() { signalstack(&_g_.m.gsignal.stack) // restore signal mask from m.sigmask and unblock essential signals - nmask := *(*uint32)(unsafe.Pointer(&_g_.m.sigmask)) + nmask := _g_.m.sigmask for i := range sigtable { if sigtable[i].flags&_SigUnblock != 0 { nmask &^= 1 << (uint32(i) - 1) @@ -158,8 +156,7 @@ func minit() { // Called from dropm to undo the effect of an minit. func unminit() { _g_ := getg() - smask := (*uint32)(unsafe.Pointer(&_g_.m.sigmask)) - sigprocmask(_SIG_SETMASK, smask, nil) + sigprocmask(_SIG_SETMASK, &_g_.m.sigmask, nil) signalstack(nil) } @@ -472,10 +469,11 @@ func signalstack(s *stack) { } func updatesigmask(m sigmask) { - sigprocmask(_SIG_SETMASK, &m[0], nil) + s := sigset(m[0]) + sigprocmask(_SIG_SETMASK, &s, nil) } func unblocksig(sig int32) { - mask := uint32(1) << (uint32(sig) - 1) + mask := sigset(1) << (uint32(sig) - 1) sigprocmask(_SIG_UNBLOCK, &mask, nil) } diff --git a/src/runtime/os1_dragonfly.go b/src/runtime/os1_dragonfly.go index a1be981f56..916a89e92f 100644 --- a/src/runtime/os1_dragonfly.go +++ b/src/runtime/os1_dragonfly.go @@ -118,11 +118,7 @@ func mpreinit(mp *m) { } func msigsave(mp *m) { - smask := (*sigset)(unsafe.Pointer(&mp.sigmask)) - if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) { - throw("insufficient storage for signal mask") - } - sigprocmask(_SIG_SETMASK, nil, smask) + sigprocmask(_SIG_SETMASK, nil, &mp.sigmask) } // Called to initialize a new m (including the bootstrap m). @@ -137,7 +133,7 @@ func minit() { signalstack(&_g_.m.gsignal.stack) // restore signal mask from m.sigmask and unblock essential signals - nmask := *(*sigset)(unsafe.Pointer(&_g_.m.sigmask)) + nmask := _g_.m.sigmask for i := range sigtable { if sigtable[i].flags&_SigUnblock != 0 { nmask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31) @@ -149,8 +145,7 @@ func minit() { // Called from dropm to undo the effect of an minit. func unminit() { _g_ := getg() - smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask)) - sigprocmask(_SIG_SETMASK, smask, nil) + sigprocmask(_SIG_SETMASK, &_g_.m.sigmask, nil) signalstack(nil) } diff --git a/src/runtime/os1_freebsd.go b/src/runtime/os1_freebsd.go index a325620fe6..9f6f8407a6 100644 --- a/src/runtime/os1_freebsd.go +++ b/src/runtime/os1_freebsd.go @@ -121,11 +121,7 @@ func mpreinit(mp *m) { } func msigsave(mp *m) { - smask := (*sigset)(unsafe.Pointer(&mp.sigmask)) - if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) { - throw("insufficient storage for signal mask") - } - sigprocmask(_SIG_SETMASK, nil, smask) + sigprocmask(_SIG_SETMASK, nil, &mp.sigmask) } // Called to initialize a new m (including the bootstrap m). @@ -143,7 +139,7 @@ func minit() { signalstack(&_g_.m.gsignal.stack) // restore signal mask from m.sigmask and unblock essential signals - nmask := *(*sigset)(unsafe.Pointer(&_g_.m.sigmask)) + nmask := _g_.m.sigmask for i := range sigtable { if sigtable[i].flags&_SigUnblock != 0 { nmask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31) @@ -155,8 +151,7 @@ func minit() { // Called from dropm to undo the effect of an minit. func unminit() { _g_ := getg() - smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask)) - sigprocmask(_SIG_SETMASK, smask, nil) + sigprocmask(_SIG_SETMASK, &_g_.m.sigmask, nil) signalstack(nil) } diff --git a/src/runtime/os1_linux.go b/src/runtime/os1_linux.go index 8b5cdd3465..5977b8437f 100644 --- a/src/runtime/os1_linux.go +++ b/src/runtime/os1_linux.go @@ -198,10 +198,7 @@ func mpreinit(mp *m) { } func msigsave(mp *m) { - smask := (*sigset)(unsafe.Pointer(&mp.sigmask)) - if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) { - throw("insufficient storage for signal mask") - } + smask := &mp.sigmask rtsigprocmask(_SIG_SETMASK, nil, smask, int32(unsafe.Sizeof(*smask))) } @@ -218,7 +215,7 @@ func minit() { _g_.m.procid = uint64(gettid()) // restore signal mask from m.sigmask and unblock essential signals - nmask := *(*sigset)(unsafe.Pointer(&_g_.m.sigmask)) + nmask := _g_.m.sigmask for i := range sigtable { if sigtable[i].flags&_SigUnblock != 0 { sigdelset(&nmask, i) @@ -230,7 +227,7 @@ func minit() { // Called from dropm to undo the effect of an minit. func unminit() { _g_ := getg() - smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask)) + smask := &_g_.m.sigmask rtsigprocmask(_SIG_SETMASK, smask, nil, int32(unsafe.Sizeof(*smask))) signalstack(nil) } diff --git a/src/runtime/os1_nacl.go b/src/runtime/os1_nacl.go index ad4329cecd..3e98261601 100644 --- a/src/runtime/os1_nacl.go +++ b/src/runtime/os1_nacl.go @@ -6,6 +6,8 @@ package runtime import "unsafe" +type sigset struct{} + // Called to initialize a new m (including the bootstrap m). // Called on the parent thread (main thread in case of bootstrap), can allocate memory. func mpreinit(mp *m) { diff --git a/src/runtime/os1_netbsd.go b/src/runtime/os1_netbsd.go index 3e77d248f7..3e19115a85 100644 --- a/src/runtime/os1_netbsd.go +++ b/src/runtime/os1_netbsd.go @@ -139,11 +139,7 @@ func mpreinit(mp *m) { } func msigsave(mp *m) { - smask := (*sigset)(unsafe.Pointer(&mp.sigmask)) - if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) { - throw("insufficient storage for signal mask") - } - sigprocmask(_SIG_SETMASK, nil, smask) + sigprocmask(_SIG_SETMASK, nil, &mp.sigmask) } // Called to initialize a new m (including the bootstrap m). @@ -156,7 +152,7 @@ func minit() { signalstack(&_g_.m.gsignal.stack) // restore signal mask from m.sigmask and unblock essential signals - nmask := *(*sigset)(unsafe.Pointer(&_g_.m.sigmask)) + nmask := _g_.m.sigmask for i := range sigtable { if sigtable[i].flags&_SigUnblock != 0 { nmask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31) @@ -168,8 +164,7 @@ func minit() { // Called from dropm to undo the effect of an minit. func unminit() { _g_ := getg() - smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask)) - sigprocmask(_SIG_SETMASK, smask, nil) + sigprocmask(_SIG_SETMASK, &_g_.m.sigmask, nil) signalstack(nil) } diff --git a/src/runtime/os1_openbsd.go b/src/runtime/os1_openbsd.go index 11034a64f6..8c770a72d0 100644 --- a/src/runtime/os1_openbsd.go +++ b/src/runtime/os1_openbsd.go @@ -22,9 +22,11 @@ const ( _CLOCK_MONOTONIC = 3 ) +type sigset uint32 + const ( - sigset_none = uint32(0) - sigset_all = ^uint32(0) + sigset_none = sigset(0) + sigset_all = ^sigset(0) ) // From OpenBSD's @@ -149,11 +151,7 @@ func mpreinit(mp *m) { } func msigsave(mp *m) { - smask := (*uint32)(unsafe.Pointer(&mp.sigmask)) - if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) { - throw("insufficient storage for signal mask") - } - *smask = sigprocmask(_SIG_BLOCK, 0) + mp.sigmask = sigprocmask(_SIG_BLOCK, 0) } // Called to initialize a new m (including the bootstrap m). @@ -168,7 +166,7 @@ func minit() { signalstack(&_g_.m.gsignal.stack) // restore signal mask from m.sigmask and unblock essential signals - nmask := *(*uint32)(unsafe.Pointer(&_g_.m.sigmask)) + nmask := _g_.m.sigmask for i := range sigtable { if sigtable[i].flags&_SigUnblock != 0 { nmask &^= 1 << (uint32(i) - 1) @@ -180,8 +178,7 @@ func minit() { // Called from dropm to undo the effect of an minit. func unminit() { _g_ := getg() - smask := *(*uint32)(unsafe.Pointer(&_g_.m.sigmask)) - sigprocmask(_SIG_SETMASK, smask) + sigprocmask(_SIG_SETMASK, _g_.m.sigmask) signalstack(nil) } @@ -203,7 +200,7 @@ func setsig(i int32, fn uintptr, restart bool) { if restart { sa.sa_flags |= _SA_RESTART } - sa.sa_mask = sigset_all + sa.sa_mask = uint32(sigset_all) if fn == funcPC(sighandler) { fn = funcPC(sigtramp) } @@ -237,10 +234,10 @@ func signalstack(s *stack) { } func updatesigmask(m sigmask) { - sigprocmask(_SIG_SETMASK, m[0]) + sigprocmask(_SIG_SETMASK, sigset(m[0])) } func unblocksig(sig int32) { - mask := uint32(1) << (uint32(sig) - 1) + mask := sigset(1) << (uint32(sig) - 1) sigprocmask(_SIG_UNBLOCK, mask) } diff --git a/src/runtime/os1_plan9.go b/src/runtime/os1_plan9.go index bc7ce65daf..06329da88e 100644 --- a/src/runtime/os1_plan9.go +++ b/src/runtime/os1_plan9.go @@ -9,6 +9,8 @@ import ( "unsafe" ) +type sigset struct{} + // Called to initialize a new m (including the bootstrap m). // Called on the parent thread (main thread in case of bootstrap), can allocate memory. func mpreinit(mp *m) { diff --git a/src/runtime/os1_windows.go b/src/runtime/os1_windows.go index 8134543578..db1b8e4937 100644 --- a/src/runtime/os1_windows.go +++ b/src/runtime/os1_windows.go @@ -99,6 +99,8 @@ var ( _GetQueuedCompletionStatusEx stdFunction ) +type sigset struct{} + // Call a Windows function with stdcall conventions, // and switch to os stack during the call. func asmstdcall(fn unsafe.Pointer) diff --git a/src/runtime/os3_solaris.go b/src/runtime/os3_solaris.go index 3ac121a7b8..c92722b7a2 100644 --- a/src/runtime/os3_solaris.go +++ b/src/runtime/os3_solaris.go @@ -193,11 +193,7 @@ func mpreinit(mp *m) { func miniterrno() func msigsave(mp *m) { - smask := (*sigset)(unsafe.Pointer(&mp.sigmask)) - if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) { - throw("insufficient storage for signal mask") - } - sigprocmask(_SIG_SETMASK, nil, smask) + sigprocmask(_SIG_SETMASK, nil, &mp.sigmask) } // Called to initialize a new m (including the bootstrap m). @@ -209,7 +205,7 @@ func minit() { signalstack(&_g_.m.gsignal.stack) // restore signal mask from m.sigmask and unblock essential signals - nmask := *(*sigset)(unsafe.Pointer(&_g_.m.sigmask)) + nmask := _g_.m.sigmask for i := range sigtable { if sigtable[i].flags&_SigUnblock != 0 { nmask.__sigbits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31) @@ -221,8 +217,7 @@ func minit() { // Called from dropm to undo the effect of an minit. func unminit() { _g_ := getg() - smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask)) - sigprocmask(_SIG_SETMASK, smask, nil) + sigprocmask(_SIG_SETMASK, &_g_.m.sigmask, nil) signalstack(nil) } diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go index 7a70639b02..75a6eebb70 100644 --- a/src/runtime/os_darwin.go +++ b/src/runtime/os_darwin.go @@ -24,7 +24,7 @@ func mach_thread_self() uint32 func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 //go:noescape -func sigprocmask(how uint32, new, old *uint32) +func sigprocmask(how uint32, new, old *sigset) //go:noescape func sigaction(mode uint32, new, old *sigactiont) diff --git a/src/runtime/os_openbsd.go b/src/runtime/os_openbsd.go index 12f4cd1a24..b6285e4972 100644 --- a/src/runtime/os_openbsd.go +++ b/src/runtime/os_openbsd.go @@ -18,7 +18,7 @@ func sigaction(sig int32, new, old *sigactiont) func sigaltstack(new, old *stackt) //go:noescape -func sigprocmask(mode int32, new uint32) uint32 +func sigprocmask(mode int32, new sigset) sigset //go:noescape func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go index eb7b30a344..9e91832370 100644 --- a/src/runtime/runtime2.go +++ b/src/runtime/runtime2.go @@ -273,7 +273,7 @@ type m struct { // Fields not known to debuggers. procid uint64 // for debuggers, but offset not hard-coded gsignal *g // signal-handling g - sigmask [4]uintptr // storage for saved signal mask + sigmask sigset // storage for saved signal mask tls [6]uintptr // thread-local storage (for x86 extern register) mstartfn func() curg *g // current running goroutine