mirror of
https://github.com/golang/go
synced 2024-11-26 01:57:56 -07:00
runtime: merge timerMoving into timerModifying
timerMoving is just a kind of "locked for modification", so merge it into timerModifying. This is part of a larger simplification of the state set. [This is one CL in a refactoring stack making very small changes in each step, so that any subtle bugs that we miss can be more easily pinpointed to a small change.] Change-Id: I5379122f96d9921ecda7a6a37cabd6c6b4d529a4 Reviewed-on: https://go-review.googlesource.com/c/go/+/564121 Reviewed-by: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
09bfea95cf
commit
3be36e9b20
@ -77,7 +77,6 @@ type timer struct {
|
|||||||
// timerDeleted -> do nothing
|
// timerDeleted -> do nothing
|
||||||
// timerRemoved -> do nothing
|
// timerRemoved -> do nothing
|
||||||
// timerRunning -> wait until status changes
|
// timerRunning -> wait until status changes
|
||||||
// timerMoving -> wait until status changes
|
|
||||||
// timerModifying -> wait until status changes
|
// timerModifying -> wait until status changes
|
||||||
// modtimer:
|
// modtimer:
|
||||||
// timerWaiting -> timerModifying -> timerModified
|
// timerWaiting -> timerModifying -> timerModified
|
||||||
@ -86,21 +85,19 @@ type timer struct {
|
|||||||
// timerRemoved -> timerModifying -> timerWaiting
|
// timerRemoved -> timerModifying -> timerWaiting
|
||||||
// timerDeleted -> timerModifying -> timerModified
|
// timerDeleted -> timerModifying -> timerModified
|
||||||
// timerRunning -> wait until status changes
|
// timerRunning -> wait until status changes
|
||||||
// timerMoving -> wait until status changes
|
|
||||||
// timerModifying -> wait until status changes
|
// timerModifying -> wait until status changes
|
||||||
// adjusttimers (looks in P's timer heap):
|
// adjusttimers (looks in P's timer heap):
|
||||||
// timerDeleted -> timerModifying -> timerRemoved
|
// timerDeleted -> timerModifying -> timerRemoved
|
||||||
// timerModified -> timerMoving -> timerWaiting
|
// timerModified -> timerModifying -> timerWaiting
|
||||||
// runtimer (looks in P's timer heap):
|
// runtimer (looks in P's timer heap):
|
||||||
// timerNoStatus -> panic: uninitialized timer
|
// timerNoStatus -> panic: uninitialized timer
|
||||||
// timerWaiting -> timerWaiting or
|
// timerWaiting -> timerWaiting or
|
||||||
// timerWaiting -> timerRunning -> timerNoStatus or
|
// timerWaiting -> timerRunning -> timerNoStatus or
|
||||||
// timerWaiting -> timerRunning -> timerWaiting
|
// timerWaiting -> timerRunning -> timerWaiting
|
||||||
// timerModifying -> wait until status changes
|
// timerModifying -> wait until status changes
|
||||||
// timerModified -> timerMoving -> timerWaiting
|
// timerModified -> timerModifying -> timerWaiting
|
||||||
// timerDeleted -> timerModifying -> timerRemoved
|
// timerDeleted -> timerModifying -> timerRemoved
|
||||||
// timerRunning -> panic: concurrent runtimer calls
|
// timerRunning -> panic: concurrent runtimer calls
|
||||||
// timerMoving -> panic: inconsistent timer heap
|
|
||||||
|
|
||||||
// Values for the timer status field.
|
// Values for the timer status field.
|
||||||
const (
|
const (
|
||||||
@ -132,10 +129,6 @@ const (
|
|||||||
// The timer is in some P's heap, possibly in the wrong place
|
// The timer is in some P's heap, possibly in the wrong place
|
||||||
// (the right place by .when; the wrong place by .nextwhen).
|
// (the right place by .when; the wrong place by .nextwhen).
|
||||||
timerModified
|
timerModified
|
||||||
|
|
||||||
// The timer has been modified and is being moved.
|
|
||||||
// The timer will only have this status briefly.
|
|
||||||
timerMoving
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// maxWhen is the maximum value for timer's when field.
|
// maxWhen is the maximum value for timer's when field.
|
||||||
@ -281,7 +274,7 @@ func deltimer(t *timer) bool {
|
|||||||
case timerDeleted, timerRemoved:
|
case timerDeleted, timerRemoved:
|
||||||
// Timer was already run.
|
// Timer was already run.
|
||||||
return false
|
return false
|
||||||
case timerRunning, timerMoving, timerModifying:
|
case timerRunning, timerModifying:
|
||||||
// The timer is being run or modified, by a different P.
|
// The timer is being run or modified, by a different P.
|
||||||
// Wait for it to complete.
|
// Wait for it to complete.
|
||||||
osyield()
|
osyield()
|
||||||
@ -371,14 +364,10 @@ loop:
|
|||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
releasem(mp)
|
releasem(mp)
|
||||||
case timerRunning, timerMoving:
|
case timerRunning, timerModifying:
|
||||||
// The timer is being run or moved, by a different P.
|
// The timer is being run or modified, by a different P.
|
||||||
// Wait for it to complete.
|
// Wait for it to complete.
|
||||||
osyield()
|
osyield()
|
||||||
case timerModifying:
|
|
||||||
// Multiple simultaneous calls to modtimer.
|
|
||||||
// Wait for the other call to complete.
|
|
||||||
osyield()
|
|
||||||
default:
|
default:
|
||||||
badTimer()
|
badTimer()
|
||||||
}
|
}
|
||||||
@ -468,7 +457,7 @@ func cleantimers(pp *p) {
|
|||||||
}
|
}
|
||||||
pp.deletedTimers.Add(-1)
|
pp.deletedTimers.Add(-1)
|
||||||
case timerModified:
|
case timerModified:
|
||||||
if !t.status.CompareAndSwap(s, timerMoving) {
|
if !t.status.CompareAndSwap(s, timerModifying) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Now we can change the when field.
|
// Now we can change the when field.
|
||||||
@ -476,7 +465,7 @@ func cleantimers(pp *p) {
|
|||||||
// Move t to the right position.
|
// Move t to the right position.
|
||||||
dodeltimer0(pp)
|
dodeltimer0(pp)
|
||||||
doaddtimer(pp, t)
|
doaddtimer(pp, t)
|
||||||
if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
|
if !t.status.CompareAndSwap(timerModifying, timerWaiting) {
|
||||||
badTimer()
|
badTimer()
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -517,23 +506,23 @@ func moveTimers(pp *p, timers []*timer) {
|
|||||||
for {
|
for {
|
||||||
switch s := t.status.Load(); s {
|
switch s := t.status.Load(); s {
|
||||||
case timerWaiting:
|
case timerWaiting:
|
||||||
if !t.status.CompareAndSwap(s, timerMoving) {
|
if !t.status.CompareAndSwap(s, timerModifying) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
t.pp = 0
|
t.pp = 0
|
||||||
doaddtimer(pp, t)
|
doaddtimer(pp, t)
|
||||||
if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
|
if !t.status.CompareAndSwap(timerModifying, timerWaiting) {
|
||||||
badTimer()
|
badTimer()
|
||||||
}
|
}
|
||||||
break loop
|
break loop
|
||||||
case timerModified:
|
case timerModified:
|
||||||
if !t.status.CompareAndSwap(s, timerMoving) {
|
if !t.status.CompareAndSwap(s, timerModifying) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
t.when = t.nextwhen
|
t.when = t.nextwhen
|
||||||
t.pp = 0
|
t.pp = 0
|
||||||
doaddtimer(pp, t)
|
doaddtimer(pp, t)
|
||||||
if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
|
if !t.status.CompareAndSwap(timerModifying, timerWaiting) {
|
||||||
badTimer()
|
badTimer()
|
||||||
}
|
}
|
||||||
break loop
|
break loop
|
||||||
@ -550,7 +539,7 @@ func moveTimers(pp *p, timers []*timer) {
|
|||||||
case timerNoStatus, timerRemoved:
|
case timerNoStatus, timerRemoved:
|
||||||
// We should not see these status values in a timers heap.
|
// We should not see these status values in a timers heap.
|
||||||
badTimer()
|
badTimer()
|
||||||
case timerRunning, timerMoving:
|
case timerRunning:
|
||||||
// Some other P thinks it owns this timer,
|
// Some other P thinks it owns this timer,
|
||||||
// which should not happen.
|
// which should not happen.
|
||||||
badTimer()
|
badTimer()
|
||||||
@ -607,15 +596,15 @@ func adjusttimers(pp *p, now int64, force bool) {
|
|||||||
changed = true
|
changed = true
|
||||||
}
|
}
|
||||||
case timerModified:
|
case timerModified:
|
||||||
if t.status.CompareAndSwap(s, timerMoving) {
|
if t.status.CompareAndSwap(s, timerModifying) {
|
||||||
// Now we can change the when field.
|
// Now we can change the when field.
|
||||||
t.when = t.nextwhen
|
t.when = t.nextwhen
|
||||||
changed = true
|
changed = true
|
||||||
if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
|
if !t.status.CompareAndSwap(timerModifying, timerWaiting) {
|
||||||
badTimer()
|
badTimer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case timerNoStatus, timerRunning, timerRemoved, timerMoving:
|
case timerNoStatus, timerRunning, timerRemoved:
|
||||||
badTimer()
|
badTimer()
|
||||||
case timerWaiting:
|
case timerWaiting:
|
||||||
// OK, nothing to do.
|
// OK, nothing to do.
|
||||||
@ -759,13 +748,13 @@ func runtimer(pp *p, now int64) int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case timerModified:
|
case timerModified:
|
||||||
if !t.status.CompareAndSwap(s, timerMoving) {
|
if !t.status.CompareAndSwap(s, timerModifying) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
t.when = t.nextwhen
|
t.when = t.nextwhen
|
||||||
dodeltimer0(pp)
|
dodeltimer0(pp)
|
||||||
doaddtimer(pp, t)
|
doaddtimer(pp, t)
|
||||||
if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
|
if !t.status.CompareAndSwap(timerModifying, timerWaiting) {
|
||||||
badTimer()
|
badTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -776,7 +765,7 @@ func runtimer(pp *p, now int64) int64 {
|
|||||||
case timerNoStatus, timerRemoved:
|
case timerNoStatus, timerRemoved:
|
||||||
// Should not see a new or inactive timer on the heap.
|
// Should not see a new or inactive timer on the heap.
|
||||||
badTimer()
|
badTimer()
|
||||||
case timerRunning, timerMoving:
|
case timerRunning:
|
||||||
// These should only be set when timers are locked,
|
// These should only be set when timers are locked,
|
||||||
// and we didn't do it.
|
// and we didn't do it.
|
||||||
badTimer()
|
badTimer()
|
||||||
|
Loading…
Reference in New Issue
Block a user