1
0
mirror of https://github.com/golang/go synced 2024-09-29 07:24:32 -06: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:
Russ Cox 2024-02-14 11:56:58 -05:00
parent 09bfea95cf
commit 3be36e9b20

View File

@ -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()