]> 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)
committerRuss Cox <rsc@golang.org>
Tue, 24 Nov 2015 17:16:47 +0000 (17:16 +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.

[Replay of CL 16942 by Elias Naur.]

Change-Id: I98f144d626033ae5318576115ed635415ac71b2c
Reviewed-on: https://go-review.googlesource.com/17033
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Russ Cox <rsc@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 fd5637f953a8ff0e803e1d06df9c52f9ae3c60fd..e0bfaa9f77fcd32a1a911be84cea271474db91d3 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)
@@ -132,17 +134,12 @@ func mpreinit(mp *m) {
 
 //go:nosplit
 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)
 }
 
 //go:nosplit
 func msigrestore(mp *m) {
-       smask := (*uint32)(unsafe.Pointer(&mp.sigmask))
-       sigprocmask(_SIG_SETMASK, smask, nil)
+       sigprocmask(_SIG_SETMASK, &mp.sigmask, nil)
 }
 
 //go:nosplit
@@ -158,7 +155,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)
@@ -483,10 +480,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 3f17da279ea814fca042c2c8e0fd6420ae55b15d..56fb733467232e2a61d1a63585c200ff682dfcef 100644 (file)
@@ -119,17 +119,12 @@ func mpreinit(mp *m) {
 
 //go:nosplit
 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)
 }
 
 //go:nosplit
 func msigrestore(mp *m) {
-       smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
-       sigprocmask(_SIG_SETMASK, smask, nil)
+       sigprocmask(_SIG_SETMASK, &mp.sigmask, nil)
 }
 
 //go:nosplit
@@ -149,7 +144,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)
index 7aa705ed0660415cc24ab3817a07b912c0886066..347b57322a3c8225045d59451766a7bdbf684f74 100644 (file)
@@ -122,17 +122,12 @@ func mpreinit(mp *m) {
 
 //go:nosplit
 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)
 }
 
 //go:nosplit
 func msigrestore(mp *m) {
-       smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
-       sigprocmask(_SIG_SETMASK, smask, nil)
+       sigprocmask(_SIG_SETMASK, &mp.sigmask, nil)
 }
 
 //go:nosplit
@@ -155,7 +150,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)
index cb73500a2f794c25a8fd1e36111d3946052233e0..e6e3770194284104478d06efa8bc12830a55eaf6 100644 (file)
@@ -199,16 +199,13 @@ func mpreinit(mp *m) {
 
 //go:nosplit
 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)))
 }
 
 //go:nosplit
 func msigrestore(mp *m) {
-       smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
+       smask := &mp.sigmask
        rtsigprocmask(_SIG_SETMASK, smask, nil, int32(unsafe.Sizeof(*smask)))
 }
 
@@ -230,7 +227,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)
index c2ceb1724ee12c67c692bf2d4fb7a8fe98277a48..c7212613697911fd076cf80285807ebb39de716c 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 767c535eecca77ffcb4b44a2afcd9a898dfde74b..c769c87d0579f4c86a54d06ac6e894e12513a138 100644 (file)
@@ -140,17 +140,12 @@ func mpreinit(mp *m) {
 
 //go:nosplit
 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)
 }
 
 //go:nosplit
 func msigrestore(mp *m) {
-       smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
-       sigprocmask(_SIG_SETMASK, smask, nil)
+       sigprocmask(_SIG_SETMASK, &mp.sigmask, nil)
 }
 
 //go:nosplit
@@ -168,7 +163,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)
index 0cfb1348afecd913e4cb3dba4aa960a25959fab7..b93788e4c2ad8711e3e51db205e8252758f5fae7 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>
@@ -150,17 +152,12 @@ func mpreinit(mp *m) {
 
 //go:nosplit
 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)
 }
 
 //go:nosplit
 func msigrestore(mp *m) {
-       smask := *(*uint32)(unsafe.Pointer(&mp.sigmask))
-       sigprocmask(_SIG_SETMASK, smask)
+       sigprocmask(_SIG_SETMASK, mp.sigmask)
 }
 
 //go:nosplit
@@ -180,7 +177,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)
@@ -213,7 +210,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)
        }
@@ -248,10 +245,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 70cd158470ad6d81845d311ee85aac7f51504668..a75e956d17a43951b2aba83c012a8b184d4faaf8 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 90e03674a406915401bc987461ab99c961e7abcb..a59e9ec88cb5fa2c71baf0c1d6fa361fabb8abb1 100644 (file)
@@ -97,6 +97,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 ad697487b00061363a276952e4bd0d4e3c5e7eec..0e6d2e55da34868e01762a0b4d82d047e72991ff 100644 (file)
@@ -194,17 +194,12 @@ func miniterrno()
 
 //go:nosplit
 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)
 }
 
 //go:nosplit
 func msigrestore(mp *m) {
-       smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
-       sigprocmask(_SIG_SETMASK, smask, nil)
+       sigprocmask(_SIG_SETMASK, &mp.sigmask, nil)
 }
 
 //go:nosplit
@@ -221,7 +216,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)
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 05300106f602896cc711cc1e3d4aaa56210a8a6e..cfe45894480e33b7cbaaa475ba9a005d6d166288 100644 (file)
@@ -284,7 +284,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