aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2015-11-19 13:26:43 -0500
committerAustin Clements <austin@google.com>2015-11-23 19:13:15 +0000
commit22e57c6655288e129fa807eecf936fdf5ac2ced8 (patch)
tree1faca9cc0effe406091c7108ad47dbf9acd1f62d /src/runtime
parent041787280976d0bad15c646fc7c7bbfef76d7ee5 (diff)
downloadgo-22e57c6655288e129fa807eecf936fdf5ac2ced8.tar.xz
runtime: make stack barrier locking more robust
The stack barrier locking functions use a simple cas lock because they need to support trylock, but currently don't increment g.m.locks. This is okay right now because they always run on the system stack or the signal stack and are hence non-preemtible, but this could lead to difficult-to-reproduce deadlocks if these conditions change in the future. Make these functions more robust by incrementing g.m.locks and making them nosplit to enforce non-preemtibility. Change-Id: I73d60a35bd2ad2d81c73aeb20dbd37665730eb1b Reviewed-on: https://go-review.googlesource.com/17058 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ingo Oeser <nightlyone@googlemail.com> Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/mstkbar.go12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/runtime/mstkbar.go b/src/runtime/mstkbar.go
index 6f5b459853..1c1c2eaf0a 100644
--- a/src/runtime/mstkbar.go
+++ b/src/runtime/mstkbar.go
@@ -300,16 +300,26 @@ func setNextBarrierPC(pc uintptr) {
// This is necessary because a sigprof during barrier installation or
// removal could observe inconsistencies between the stkbar array and
// the stack itself and crash.
+//
+//go:nosplit
func gcLockStackBarriers(gp *g) {
+ acquirem()
for !atomic.Cas(&gp.stackLock, 0, 1) {
osyield()
}
}
+//go:nosplit
func gcTryLockStackBarriers(gp *g) bool {
- return atomic.Cas(&gp.stackLock, 0, 1)
+ mp := acquirem()
+ result := atomic.Cas(&gp.stackLock, 0, 1)
+ if !result {
+ releasem(mp)
+ }
+ return result
}
func gcUnlockStackBarriers(gp *g) {
atomic.Store(&gp.stackLock, 0)
+ releasem(getg().m)
}