diff options
author | Ian Lance Taylor <iant@golang.org> | 2021-06-10 12:37:34 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2021-06-10 14:41:23 -0700 |
commit | ee52bf609bac45b3c251858a69071262f46ee89c (patch) | |
tree | 4c079eab4884dc9c32e6f62fe9e2f0ff0d784306 /libgo/go/runtime/proc.go | |
parent | 00d07ec6e12451acc7a290cd93be03bed50cb666 (diff) | |
download | gcc-ee52bf609bac45b3c251858a69071262f46ee89c.zip gcc-ee52bf609bac45b3c251858a69071262f46ee89c.tar.gz gcc-ee52bf609bac45b3c251858a69071262f46ee89c.tar.bz2 |
libgo: update to Go1.16.5 release
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/326772
Diffstat (limited to 'libgo/go/runtime/proc.go')
-rw-r--r-- | libgo/go/runtime/proc.go | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go index eec44db..037e779 100644 --- a/libgo/go/runtime/proc.go +++ b/libgo/go/runtime/proc.go @@ -1287,6 +1287,9 @@ func mPark() { g := getg() for { notesleep(&g.m.park) + // Note, because of signal handling by this parked m, + // a preemptive mDoFixup() may actually occur via + // mDoFixupAndOSYield(). (See golang.org/issue/44193) noteclear(&g.m.park) if !mDoFixup() { return @@ -1949,9 +1952,21 @@ var mFixupRace struct { // mDoFixup runs any outstanding fixup function for the running m. // Returns true if a fixup was outstanding and actually executed. // +// Note: to avoid deadlocks, and the need for the fixup function +// itself to be async safe, signals are blocked for the working m +// while it holds the mFixup lock. (See golang.org/issue/44193) +// //go:nosplit func mDoFixup() bool { _g_ := getg() + if used := atomic.Load(&_g_.m.mFixup.used); used == 0 { + return false + } + + // slow path - if fixup fn is used, block signals and lock. + var sigmask sigset + sigsave(&sigmask) + sigblock(false) lock(&_g_.m.mFixup.lock) fn := _g_.m.mFixup.fn if fn != nil { @@ -1972,9 +1987,20 @@ func mDoFixup() bool { fn(false) } unlock(&_g_.m.mFixup.lock) + msigrestore(sigmask) return fn != nil } +// mDoFixupAndOSYield is called when an m is unable to send a signal +// because the allThreadsSyscall mechanism is in progress. That is, an +// mPark() has been interrupted with this signal handler so we need to +// ensure the fixup is executed from this context. +//go:nosplit +func mDoFixupAndOSYield() { + mDoFixup() + osyield() +} + // templateThread is a thread in a known-good state that exists solely // to start new threads in known-good states when the calling thread // may not be in a good state. |