]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: use a proper type, sigset, for m.sigmask
authorElias Naur <elias.naur@gmail.com>
Tue, 17 Nov 2015 10:41:06 +0000 (11:41 +0100)
committerIan Lance Taylor <iant@golang.org>
Tue, 17 Nov 2015 21:23:06 +0000 (21:23 +0000)
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 <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

13 files changed:
src/runtime/os1_darwin.go
src/runtime/os1_dragonfly.go
src/runtime/os1_freebsd.go
src/runtime/os1_linux.go
src/runtime/os1_nacl.go
src/runtime/os1_netbsd.go
src/runtime/os1_openbsd.go
src/runtime/os1_plan9.go
src/runtime/os1_windows.go
src/runtime/os3_solaris.go
src/runtime/os_darwin.go
src/runtime/os_openbsd.go
src/runtime/runtime2.go

index ba38a78ed1974dff4e022da9eed66e8fd6f90628..e702739508e2c3f0c59d7eb590492db7cf51062e 100644 (file)
@@ -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)
 }
index a1be981f56b88c4fc9417d683767df263cab1703..916a89e92ff6c9f354fc9851b343cebfe96ccb1a 100644 (file)
@@ -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)
 }
 
index a325620fe6d02cd79af47d4a9f4889e26ae784bd..9f6f8407a6d9d483274b29132909ff34fbb14946 100644 (file)
@@ -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)
 }
 
index 8b5cdd346557daef0ac631cfbea3295a28e9cb09..5977b8437fa33cd33f9d47d65c2f5dc2b84402e6 100644 (file)
@@ -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)
 }
index ad4329cecd12ddd39fed8627c329948a0c1f55f9..3e982616018fce617f3158fb051cca531b70d795 100644 (file)
@@ -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) {
index 3e77d248f79bfa43dedf5620b9a7341ee1862e3d..3e19115a853487df981ffb8d3cfd2784a3757802 100644 (file)
@@ -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)
 }
index 11034a64f664f07dba1494274589ff0daa80c19d..8c770a72d0d12e9a4982e4c7fdf244af471f7dff 100644 (file)
@@ -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 <sys/sysctl.h>
@@ -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)
 }
index bc7ce65dafd18c02e59971c8a43360e69e4e3479..06329da88e8a8cbad7cff57388bc5e0b7924352f 100644 (file)
@@ -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) {
index 813454357824e8537c221132cca8d952777bb2c9..db1b8e4937cfee1837e02663219df2a58ac0f10e 100644 (file)
@@ -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)
index 3ac121a7b828debe83d779c63a8d3c6b2649e061..c92722b7a2677e943b8681f47ac69bca8618d823 100644 (file)
@@ -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)
 }
index 7a70639b022f0627d9a494d14e8536a83a8711f3..75a6eebb70284651f9ed256cb1b3c6453ae1d912 100644 (file)
@@ -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)
index 12f4cd1a246ed9dcda8af5ad3b437b85eb743e79..b6285e49729d6af82fbb340047160a29d76577df 100644 (file)
@@ -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
index eb7b30a344d2c059bc350b078929baf9720427e5..9e91832370124ffc9de9db71f45ea87fc22fcaa8 100644 (file)
@@ -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