mirror of
https://github.com/golang/go
synced 2024-11-19 06:54:39 -07:00
runtime: define lock order between G status and channel lock
Currently, locking a G's stack by setting its status to _Gcopystack or _Gscan is unordered with respect to channel locks. However, when we make stack shrinking concurrent, stack shrinking will need to lock the G and then acquire channel locks, which imposes an order on these. Document this lock ordering and fix closechan to respect it. Everything else already happens to respect it. For #12967. Change-Id: I4dd02675efffb3e7daa5285cf75bf24f987d90d4 Reviewed-on: https://go-review.googlesource.com/20041 Reviewed-by: Rick Hudson <rlh@golang.org> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
db72b41bcd
commit
d45bf7228f
@ -36,6 +36,10 @@ type hchan struct {
|
||||
|
||||
// lock protects all fields in hchan, as well as several
|
||||
// fields in sudogs blocked on this channel.
|
||||
//
|
||||
// Do not change another G's status while holding this lock
|
||||
// (in particular, do not ready a G), as this can deadlock
|
||||
// with stack shrinking.
|
||||
lock mutex
|
||||
}
|
||||
|
||||
@ -315,6 +319,8 @@ func closechan(c *hchan) {
|
||||
|
||||
c.closed = 1
|
||||
|
||||
var glist *g
|
||||
|
||||
// release all readers
|
||||
for {
|
||||
sg := c.recvq.dequeue()
|
||||
@ -333,7 +339,8 @@ func closechan(c *hchan) {
|
||||
if raceenabled {
|
||||
raceacquireg(gp, unsafe.Pointer(c))
|
||||
}
|
||||
goready(gp, 3)
|
||||
gp.schedlink.set(glist)
|
||||
glist = gp
|
||||
}
|
||||
|
||||
// release all writers (they will panic)
|
||||
@ -351,9 +358,18 @@ func closechan(c *hchan) {
|
||||
if raceenabled {
|
||||
raceacquireg(gp, unsafe.Pointer(c))
|
||||
}
|
||||
goready(gp, 3)
|
||||
gp.schedlink.set(glist)
|
||||
glist = gp
|
||||
}
|
||||
unlock(&c.lock)
|
||||
|
||||
// Ready all Gs now that we've dropped the channel lock.
|
||||
for glist != nil {
|
||||
gp := glist
|
||||
glist = glist.schedlink.ptr()
|
||||
gp.schedlink = 0
|
||||
goready(gp, 3)
|
||||
}
|
||||
}
|
||||
|
||||
// entry points for <- c from compiled code
|
||||
|
Loading…
Reference in New Issue
Block a user