mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: convert semaRoot.nwait to atomic type
For #53821 Change-Id: I686fe81268f70acc6a4c3e6b1d3ed0e07bb0d61c Reviewed-on: https://go-review.googlesource.com/c/go/+/425775 Run-TryBot: xie cui <523516579@qq.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Michael Pratt <mpratt@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> Auto-Submit: Michael Knyszek <mknyszek@google.com> Run-TryBot: Michael Pratt <mpratt@google.com>
This commit is contained in:
parent
6e74c4116a
commit
fa0e3bffb4
2 changed files with 8 additions and 8 deletions
|
|
@ -1164,7 +1164,7 @@ var Semrelease1 = semrelease1
|
||||||
|
|
||||||
func SemNwait(addr *uint32) uint32 {
|
func SemNwait(addr *uint32) uint32 {
|
||||||
root := semtable.rootFor(addr)
|
root := semtable.rootFor(addr)
|
||||||
return atomic.Load(&root.nwait)
|
return root.nwait.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
const SemTableSize = semTabSize
|
const SemTableSize = semTabSize
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,8 @@ import (
|
||||||
// BenchmarkSemTable/OneAddrCollision/* for a benchmark that exercises this.
|
// BenchmarkSemTable/OneAddrCollision/* for a benchmark that exercises this.
|
||||||
type semaRoot struct {
|
type semaRoot struct {
|
||||||
lock mutex
|
lock mutex
|
||||||
treap *sudog // root of balanced tree of unique waiters.
|
treap *sudog // root of balanced tree of unique waiters.
|
||||||
nwait uint32 // Number of waiters. Read w/o the lock.
|
nwait atomic.Uint32 // Number of waiters. Read w/o the lock.
|
||||||
}
|
}
|
||||||
|
|
||||||
var semtable semTable
|
var semtable semTable
|
||||||
|
|
@ -137,10 +137,10 @@ func semacquire1(addr *uint32, lifo bool, profile semaProfileFlags, skipframes i
|
||||||
for {
|
for {
|
||||||
lockWithRank(&root.lock, lockRankRoot)
|
lockWithRank(&root.lock, lockRankRoot)
|
||||||
// Add ourselves to nwait to disable "easy case" in semrelease.
|
// Add ourselves to nwait to disable "easy case" in semrelease.
|
||||||
atomic.Xadd(&root.nwait, 1)
|
root.nwait.Add(1)
|
||||||
// Check cansemacquire to avoid missed wakeup.
|
// Check cansemacquire to avoid missed wakeup.
|
||||||
if cansemacquire(addr) {
|
if cansemacquire(addr) {
|
||||||
atomic.Xadd(&root.nwait, -1)
|
root.nwait.Add(-1)
|
||||||
unlock(&root.lock)
|
unlock(&root.lock)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -169,13 +169,13 @@ func semrelease1(addr *uint32, handoff bool, skipframes int) {
|
||||||
// Easy case: no waiters?
|
// Easy case: no waiters?
|
||||||
// This check must happen after the xadd, to avoid a missed wakeup
|
// This check must happen after the xadd, to avoid a missed wakeup
|
||||||
// (see loop in semacquire).
|
// (see loop in semacquire).
|
||||||
if atomic.Load(&root.nwait) == 0 {
|
if root.nwait.Load() == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Harder case: search for a waiter and wake it.
|
// Harder case: search for a waiter and wake it.
|
||||||
lockWithRank(&root.lock, lockRankRoot)
|
lockWithRank(&root.lock, lockRankRoot)
|
||||||
if atomic.Load(&root.nwait) == 0 {
|
if root.nwait.Load() == 0 {
|
||||||
// The count is already consumed by another goroutine,
|
// The count is already consumed by another goroutine,
|
||||||
// so no need to wake up another goroutine.
|
// so no need to wake up another goroutine.
|
||||||
unlock(&root.lock)
|
unlock(&root.lock)
|
||||||
|
|
@ -183,7 +183,7 @@ func semrelease1(addr *uint32, handoff bool, skipframes int) {
|
||||||
}
|
}
|
||||||
s, t0 := root.dequeue(addr)
|
s, t0 := root.dequeue(addr)
|
||||||
if s != nil {
|
if s != nil {
|
||||||
atomic.Xadd(&root.nwait, -1)
|
root.nwait.Add(-1)
|
||||||
}
|
}
|
||||||
unlock(&root.lock)
|
unlock(&root.lock)
|
||||||
if s != nil { // May be slow or even yield, so unlock first
|
if s != nil { // May be slow or even yield, so unlock first
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue