Skip to content

Commit 7db7727

Browse files
Elias Naurianlancetaylor
Elias Naur
authored andcommitted
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 <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 07d4899 commit 7db7727

13 files changed

+45
-67
lines changed

src/runtime/os1_darwin.go

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import "unsafe"
88

99
//extern SigTabTT runtime·sigtab[];
1010

11-
var sigset_all = ^uint32(0)
11+
type sigset uint32
12+
13+
var sigset_all = ^sigset(0)
1214

1315
func unimplemented(name string) {
1416
println(name, "not implemented")
@@ -83,7 +85,7 @@ func newosproc(mp *m, stk unsafe.Pointer) {
8385
print("newosproc stk=", stk, " m=", mp, " g=", mp.g0, " id=", mp.id, " ostk=", &mp, "\n")
8486
}
8587

86-
var oset uint32
88+
var oset sigset
8789
sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
8890
errno := bsdthread_create(stk, unsafe.Pointer(mp), funcPC(mstart))
8991
sigprocmask(_SIG_SETMASK, &oset, nil)
@@ -109,7 +111,7 @@ func newosproc0(stacksize uintptr, fn unsafe.Pointer, fnarg uintptr) {
109111
}
110112
stk := unsafe.Pointer(uintptr(stack) + stacksize)
111113

112-
var oset uint32
114+
var oset sigset
113115
sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
114116
errno := bsdthread_create(stk, fn, fnarg)
115117
sigprocmask(_SIG_SETMASK, &oset, nil)
@@ -131,11 +133,7 @@ func mpreinit(mp *m) {
131133
}
132134

133135
func msigsave(mp *m) {
134-
smask := (*uint32)(unsafe.Pointer(&mp.sigmask))
135-
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
136-
throw("insufficient storage for signal mask")
137-
}
138-
sigprocmask(_SIG_SETMASK, nil, smask)
136+
sigprocmask(_SIG_SETMASK, nil, &mp.sigmask)
139137
}
140138

141139
// Called to initialize a new m (including the bootstrap m).
@@ -146,7 +144,7 @@ func minit() {
146144
signalstack(&_g_.m.gsignal.stack)
147145

148146
// restore signal mask from m.sigmask and unblock essential signals
149-
nmask := *(*uint32)(unsafe.Pointer(&_g_.m.sigmask))
147+
nmask := _g_.m.sigmask
150148
for i := range sigtable {
151149
if sigtable[i].flags&_SigUnblock != 0 {
152150
nmask &^= 1 << (uint32(i) - 1)
@@ -158,8 +156,7 @@ func minit() {
158156
// Called from dropm to undo the effect of an minit.
159157
func unminit() {
160158
_g_ := getg()
161-
smask := (*uint32)(unsafe.Pointer(&_g_.m.sigmask))
162-
sigprocmask(_SIG_SETMASK, smask, nil)
159+
sigprocmask(_SIG_SETMASK, &_g_.m.sigmask, nil)
163160
signalstack(nil)
164161
}
165162

@@ -472,10 +469,11 @@ func signalstack(s *stack) {
472469
}
473470

474471
func updatesigmask(m sigmask) {
475-
sigprocmask(_SIG_SETMASK, &m[0], nil)
472+
s := sigset(m[0])
473+
sigprocmask(_SIG_SETMASK, &s, nil)
476474
}
477475

478476
func unblocksig(sig int32) {
479-
mask := uint32(1) << (uint32(sig) - 1)
477+
mask := sigset(1) << (uint32(sig) - 1)
480478
sigprocmask(_SIG_UNBLOCK, &mask, nil)
481479
}

src/runtime/os1_dragonfly.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,7 @@ func mpreinit(mp *m) {
118118
}
119119

120120
func msigsave(mp *m) {
121-
smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
122-
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
123-
throw("insufficient storage for signal mask")
124-
}
125-
sigprocmask(_SIG_SETMASK, nil, smask)
121+
sigprocmask(_SIG_SETMASK, nil, &mp.sigmask)
126122
}
127123

128124
// Called to initialize a new m (including the bootstrap m).
@@ -137,7 +133,7 @@ func minit() {
137133
signalstack(&_g_.m.gsignal.stack)
138134

139135
// restore signal mask from m.sigmask and unblock essential signals
140-
nmask := *(*sigset)(unsafe.Pointer(&_g_.m.sigmask))
136+
nmask := _g_.m.sigmask
141137
for i := range sigtable {
142138
if sigtable[i].flags&_SigUnblock != 0 {
143139
nmask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
@@ -149,8 +145,7 @@ func minit() {
149145
// Called from dropm to undo the effect of an minit.
150146
func unminit() {
151147
_g_ := getg()
152-
smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
153-
sigprocmask(_SIG_SETMASK, smask, nil)
148+
sigprocmask(_SIG_SETMASK, &_g_.m.sigmask, nil)
154149
signalstack(nil)
155150
}
156151

src/runtime/os1_freebsd.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,7 @@ func mpreinit(mp *m) {
121121
}
122122

123123
func msigsave(mp *m) {
124-
smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
125-
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
126-
throw("insufficient storage for signal mask")
127-
}
128-
sigprocmask(_SIG_SETMASK, nil, smask)
124+
sigprocmask(_SIG_SETMASK, nil, &mp.sigmask)
129125
}
130126

131127
// Called to initialize a new m (including the bootstrap m).
@@ -143,7 +139,7 @@ func minit() {
143139
signalstack(&_g_.m.gsignal.stack)
144140

145141
// restore signal mask from m.sigmask and unblock essential signals
146-
nmask := *(*sigset)(unsafe.Pointer(&_g_.m.sigmask))
142+
nmask := _g_.m.sigmask
147143
for i := range sigtable {
148144
if sigtable[i].flags&_SigUnblock != 0 {
149145
nmask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
@@ -155,8 +151,7 @@ func minit() {
155151
// Called from dropm to undo the effect of an minit.
156152
func unminit() {
157153
_g_ := getg()
158-
smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
159-
sigprocmask(_SIG_SETMASK, smask, nil)
154+
sigprocmask(_SIG_SETMASK, &_g_.m.sigmask, nil)
160155
signalstack(nil)
161156
}
162157

src/runtime/os1_linux.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,7 @@ func mpreinit(mp *m) {
198198
}
199199

200200
func msigsave(mp *m) {
201-
smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
202-
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
203-
throw("insufficient storage for signal mask")
204-
}
201+
smask := &mp.sigmask
205202
rtsigprocmask(_SIG_SETMASK, nil, smask, int32(unsafe.Sizeof(*smask)))
206203
}
207204

@@ -218,7 +215,7 @@ func minit() {
218215
_g_.m.procid = uint64(gettid())
219216

220217
// restore signal mask from m.sigmask and unblock essential signals
221-
nmask := *(*sigset)(unsafe.Pointer(&_g_.m.sigmask))
218+
nmask := _g_.m.sigmask
222219
for i := range sigtable {
223220
if sigtable[i].flags&_SigUnblock != 0 {
224221
sigdelset(&nmask, i)
@@ -230,7 +227,7 @@ func minit() {
230227
// Called from dropm to undo the effect of an minit.
231228
func unminit() {
232229
_g_ := getg()
233-
smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
230+
smask := &_g_.m.sigmask
234231
rtsigprocmask(_SIG_SETMASK, smask, nil, int32(unsafe.Sizeof(*smask)))
235232
signalstack(nil)
236233
}

src/runtime/os1_nacl.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ package runtime
66

77
import "unsafe"
88

9+
type sigset struct{}
10+
911
// Called to initialize a new m (including the bootstrap m).
1012
// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
1113
func mpreinit(mp *m) {

src/runtime/os1_netbsd.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,7 @@ func mpreinit(mp *m) {
139139
}
140140

141141
func msigsave(mp *m) {
142-
smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
143-
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
144-
throw("insufficient storage for signal mask")
145-
}
146-
sigprocmask(_SIG_SETMASK, nil, smask)
142+
sigprocmask(_SIG_SETMASK, nil, &mp.sigmask)
147143
}
148144

149145
// Called to initialize a new m (including the bootstrap m).
@@ -156,7 +152,7 @@ func minit() {
156152
signalstack(&_g_.m.gsignal.stack)
157153

158154
// restore signal mask from m.sigmask and unblock essential signals
159-
nmask := *(*sigset)(unsafe.Pointer(&_g_.m.sigmask))
155+
nmask := _g_.m.sigmask
160156
for i := range sigtable {
161157
if sigtable[i].flags&_SigUnblock != 0 {
162158
nmask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
@@ -168,8 +164,7 @@ func minit() {
168164
// Called from dropm to undo the effect of an minit.
169165
func unminit() {
170166
_g_ := getg()
171-
smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
172-
sigprocmask(_SIG_SETMASK, smask, nil)
167+
sigprocmask(_SIG_SETMASK, &_g_.m.sigmask, nil)
173168

174169
signalstack(nil)
175170
}

src/runtime/os1_openbsd.go

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ const (
2222
_CLOCK_MONOTONIC = 3
2323
)
2424

25+
type sigset uint32
26+
2527
const (
26-
sigset_none = uint32(0)
27-
sigset_all = ^uint32(0)
28+
sigset_none = sigset(0)
29+
sigset_all = ^sigset(0)
2830
)
2931

3032
// From OpenBSD's <sys/sysctl.h>
@@ -149,11 +151,7 @@ func mpreinit(mp *m) {
149151
}
150152

151153
func msigsave(mp *m) {
152-
smask := (*uint32)(unsafe.Pointer(&mp.sigmask))
153-
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
154-
throw("insufficient storage for signal mask")
155-
}
156-
*smask = sigprocmask(_SIG_BLOCK, 0)
154+
mp.sigmask = sigprocmask(_SIG_BLOCK, 0)
157155
}
158156

159157
// Called to initialize a new m (including the bootstrap m).
@@ -168,7 +166,7 @@ func minit() {
168166
signalstack(&_g_.m.gsignal.stack)
169167

170168
// restore signal mask from m.sigmask and unblock essential signals
171-
nmask := *(*uint32)(unsafe.Pointer(&_g_.m.sigmask))
169+
nmask := _g_.m.sigmask
172170
for i := range sigtable {
173171
if sigtable[i].flags&_SigUnblock != 0 {
174172
nmask &^= 1 << (uint32(i) - 1)
@@ -180,8 +178,7 @@ func minit() {
180178
// Called from dropm to undo the effect of an minit.
181179
func unminit() {
182180
_g_ := getg()
183-
smask := *(*uint32)(unsafe.Pointer(&_g_.m.sigmask))
184-
sigprocmask(_SIG_SETMASK, smask)
181+
sigprocmask(_SIG_SETMASK, _g_.m.sigmask)
185182
signalstack(nil)
186183
}
187184

@@ -203,7 +200,7 @@ func setsig(i int32, fn uintptr, restart bool) {
203200
if restart {
204201
sa.sa_flags |= _SA_RESTART
205202
}
206-
sa.sa_mask = sigset_all
203+
sa.sa_mask = uint32(sigset_all)
207204
if fn == funcPC(sighandler) {
208205
fn = funcPC(sigtramp)
209206
}
@@ -237,10 +234,10 @@ func signalstack(s *stack) {
237234
}
238235

239236
func updatesigmask(m sigmask) {
240-
sigprocmask(_SIG_SETMASK, m[0])
237+
sigprocmask(_SIG_SETMASK, sigset(m[0]))
241238
}
242239

243240
func unblocksig(sig int32) {
244-
mask := uint32(1) << (uint32(sig) - 1)
241+
mask := sigset(1) << (uint32(sig) - 1)
245242
sigprocmask(_SIG_UNBLOCK, mask)
246243
}

src/runtime/os1_plan9.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"unsafe"
1010
)
1111

12+
type sigset struct{}
13+
1214
// Called to initialize a new m (including the bootstrap m).
1315
// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
1416
func mpreinit(mp *m) {

src/runtime/os1_windows.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ var (
9999
_GetQueuedCompletionStatusEx stdFunction
100100
)
101101

102+
type sigset struct{}
103+
102104
// Call a Windows function with stdcall conventions,
103105
// and switch to os stack during the call.
104106
func asmstdcall(fn unsafe.Pointer)

src/runtime/os3_solaris.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,7 @@ func mpreinit(mp *m) {
193193
func miniterrno()
194194

195195
func msigsave(mp *m) {
196-
smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
197-
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
198-
throw("insufficient storage for signal mask")
199-
}
200-
sigprocmask(_SIG_SETMASK, nil, smask)
196+
sigprocmask(_SIG_SETMASK, nil, &mp.sigmask)
201197
}
202198

203199
// Called to initialize a new m (including the bootstrap m).
@@ -209,7 +205,7 @@ func minit() {
209205
signalstack(&_g_.m.gsignal.stack)
210206

211207
// restore signal mask from m.sigmask and unblock essential signals
212-
nmask := *(*sigset)(unsafe.Pointer(&_g_.m.sigmask))
208+
nmask := _g_.m.sigmask
213209
for i := range sigtable {
214210
if sigtable[i].flags&_SigUnblock != 0 {
215211
nmask.__sigbits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
@@ -221,8 +217,7 @@ func minit() {
221217
// Called from dropm to undo the effect of an minit.
222218
func unminit() {
223219
_g_ := getg()
224-
smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
225-
sigprocmask(_SIG_SETMASK, smask, nil)
220+
sigprocmask(_SIG_SETMASK, &_g_.m.sigmask, nil)
226221

227222
signalstack(nil)
228223
}

src/runtime/os_darwin.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func mach_thread_self() uint32
2424
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
2525

2626
//go:noescape
27-
func sigprocmask(how uint32, new, old *uint32)
27+
func sigprocmask(how uint32, new, old *sigset)
2828

2929
//go:noescape
3030
func sigaction(mode uint32, new, old *sigactiont)

src/runtime/os_openbsd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ func sigaction(sig int32, new, old *sigactiont)
1818
func sigaltstack(new, old *stackt)
1919

2020
//go:noescape
21-
func sigprocmask(mode int32, new uint32) uint32
21+
func sigprocmask(mode int32, new sigset) sigset
2222

2323
//go:noescape
2424
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32

src/runtime/runtime2.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ type m struct {
273273
// Fields not known to debuggers.
274274
procid uint64 // for debuggers, but offset not hard-coded
275275
gsignal *g // signal-handling g
276-
sigmask [4]uintptr // storage for saved signal mask
276+
sigmask sigset // storage for saved signal mask
277277
tls [6]uintptr // thread-local storage (for x86 extern register)
278278
mstartfn func()
279279
curg *g // current running goroutine

0 commit comments

Comments
 (0)