mirror of
https://github.com/golang/go.git
synced 2025-05-25 17:31:22 +00:00
runtime: minimize time between lockextra/unlockextra
This doesn't fix a bug, but may improve performance in programs that have many concurrent calls from C to Go. The old code made several system calls between lockextra and unlockextra. That could be happening while another thread is spinning acquiring lockextra. This changes the code to not make any system calls while holding the lock. Change-Id: I50576478e478670c3d6429ad4e1b7d80f98a19d8 Reviewed-on: https://go-review.googlesource.com/18548 Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
f36ee8c249
commit
efd93a412e
@ -147,8 +147,8 @@ func msigsave(mp *m) {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func msigrestore(mp *m) {
|
||||
sigprocmask(_SIG_SETMASK, &mp.sigmask, nil)
|
||||
func msigrestore(sigmask sigset) {
|
||||
sigprocmask(_SIG_SETMASK, &sigmask, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
@ -123,8 +123,8 @@ func msigsave(mp *m) {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func msigrestore(mp *m) {
|
||||
sigprocmask(_SIG_SETMASK, &mp.sigmask, nil)
|
||||
func msigrestore(sigmask sigset) {
|
||||
sigprocmask(_SIG_SETMASK, &sigmask, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
@ -126,8 +126,8 @@ func msigsave(mp *m) {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func msigrestore(mp *m) {
|
||||
sigprocmask(_SIG_SETMASK, &mp.sigmask, nil)
|
||||
func msigrestore(sigmask sigset) {
|
||||
sigprocmask(_SIG_SETMASK, &sigmask, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
@ -213,9 +213,8 @@ func msigsave(mp *m) {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func msigrestore(mp *m) {
|
||||
smask := &mp.sigmask
|
||||
rtsigprocmask(_SIG_SETMASK, smask, nil, int32(unsafe.Sizeof(*smask)))
|
||||
func msigrestore(sigmask sigset) {
|
||||
rtsigprocmask(_SIG_SETMASK, &sigmask, nil, int32(unsafe.Sizeof(sigmask)))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
@ -22,7 +22,7 @@ func msigsave(mp *m) {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func msigrestore(mp *m) {
|
||||
func msigrestore(sigmask sigset) {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
@ -144,8 +144,8 @@ func msigsave(mp *m) {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func msigrestore(mp *m) {
|
||||
sigprocmask(_SIG_SETMASK, &mp.sigmask, nil)
|
||||
func msigrestore(sigmask sigset) {
|
||||
sigprocmask(_SIG_SETMASK, &sigmask, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
@ -156,8 +156,8 @@ func msigsave(mp *m) {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func msigrestore(mp *m) {
|
||||
sigprocmask(_SIG_SETMASK, mp.sigmask)
|
||||
func msigrestore(sigmask sigset) {
|
||||
sigprocmask(_SIG_SETMASK, sigmask)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
@ -26,7 +26,7 @@ func mpreinit(mp *m) {
|
||||
func msigsave(mp *m) {
|
||||
}
|
||||
|
||||
func msigrestore(mp *m) {
|
||||
func msigrestore(sigmask sigset) {
|
||||
}
|
||||
|
||||
func sigblock() {
|
||||
|
@ -391,7 +391,7 @@ func msigsave(mp *m) {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func msigrestore(mp *m) {
|
||||
func msigrestore(sigmask sigset) {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
@ -198,8 +198,8 @@ func msigsave(mp *m) {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func msigrestore(mp *m) {
|
||||
sigprocmask(_SIG_SETMASK, &mp.sigmask, nil)
|
||||
func msigrestore(sigmask sigset) {
|
||||
sigprocmask(_SIG_SETMASK, &sigmask, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
@ -540,6 +540,7 @@ func sigaltstack(ss *sigaltstackt, oss *sigaltstackt) /* int32 */ {
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
//go:noescape
|
||||
func sigprocmask(how int32, set *sigset, oset *sigset) /* int32 */ {
|
||||
sysvicall3(&libc_sigprocmask, uintptr(how), uintptr(unsafe.Pointer(set)), uintptr(unsafe.Pointer(oset)))
|
||||
}
|
||||
|
@ -1427,20 +1427,24 @@ func dropm() {
|
||||
// After the call to setg we can only call nosplit functions
|
||||
// with no pointer manipulation.
|
||||
mp := getg().m
|
||||
mnext := lockextra(true)
|
||||
mp.schedlink.set(mnext)
|
||||
|
||||
// Block signals before unminit.
|
||||
// Unminit unregisters the signal handling stack (but needs g on some systems).
|
||||
// Setg(nil) clears g, which is the signal handler's cue not to run Go handlers.
|
||||
// It's important not to try to handle a signal between those two steps.
|
||||
sigmask := mp.sigmask
|
||||
sigblock()
|
||||
unminit()
|
||||
|
||||
mnext := lockextra(true)
|
||||
mp.schedlink.set(mnext)
|
||||
|
||||
setg(nil)
|
||||
msigrestore(mp)
|
||||
|
||||
// Commit the release of mp.
|
||||
unlockextra(mp)
|
||||
|
||||
msigrestore(sigmask)
|
||||
}
|
||||
|
||||
// A helper function for EnsureDropM.
|
||||
|
Loading…
x
Reference in New Issue
Block a user