diff options
| author | Russ Cox <rsc@golang.org> | 2024-02-14 11:56:57 -0500 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2024-02-28 16:43:52 +0000 |
| commit | b2bd7ebafcd8588fadef6b73755ee98bc8889233 (patch) | |
| tree | b4761d34c1ce10e6a52456943c01bef6253e35e7 /src | |
| parent | 4a3c3ec9966022fd6a02e1790f71536acd6bcf1e (diff) | |
| download | go-b2bd7ebafcd8588fadef6b73755ee98bc8889233.tar.xz | |
runtime: merge timerModifiedEarlier and timerModifierLater
Nothing actually needs to know the difference between these
two states, so merge them.
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: Ia30699ac92e66467773942e7df1fb21470a6e51a
Reviewed-on: https://go-review.googlesource.com/c/go/+/564119
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/runtime/time.go | 76 |
1 files changed, 23 insertions, 53 deletions
diff --git a/src/runtime/time.go b/src/runtime/time.go index d75cab0ba8..cd4d214c79 100644 --- a/src/runtime/time.go +++ b/src/runtime/time.go @@ -72,8 +72,7 @@ type timer struct { // // deltimer: // timerWaiting -> timerModifying -> timerDeleted -// timerModifiedEarlier -> timerModifying -> timerDeleted -// timerModifiedLater -> timerModifying -> timerDeleted +// timerModified -> timerModifying -> timerDeleted // timerNoStatus -> do nothing // timerDeleted -> do nothing // timerRemoving -> do nothing @@ -82,25 +81,25 @@ type timer struct { // timerMoving -> wait until status changes // timerModifying -> wait until status changes // modtimer: -// timerWaiting -> timerModifying -> timerModifiedXX -// timerModifiedXX -> timerModifying -> timerModifiedYY +// timerWaiting -> timerModifying -> timerModified +// timerModified -> timerModifying -> timerModified // timerNoStatus -> timerModifying -> timerWaiting // timerRemoved -> timerModifying -> timerWaiting -// timerDeleted -> timerModifying -> timerModifiedXX +// timerDeleted -> timerModifying -> timerModified // timerRunning -> wait until status changes // timerMoving -> wait until status changes // timerRemoving -> wait until status changes // timerModifying -> wait until status changes // adjusttimers (looks in P's timer heap): // timerDeleted -> timerRemoving -> timerRemoved -// timerModifiedXX -> timerMoving -> timerWaiting +// timerModified -> timerMoving -> timerWaiting // runtimer (looks in P's timer heap): // timerNoStatus -> panic: uninitialized timer // timerWaiting -> timerWaiting or // timerWaiting -> timerRunning -> timerNoStatus or // timerWaiting -> timerRunning -> timerWaiting // timerModifying -> wait until status changes -// timerModifiedXX -> timerMoving -> timerWaiting +// timerModified -> timerMoving -> timerWaiting // timerDeleted -> timerRemoving -> timerRemoved // timerRunning -> panic: concurrent runtimer calls // timerRemoved -> panic: inconsistent timer heap @@ -136,15 +135,11 @@ const ( // The timer will only have this status briefly. timerModifying - // The timer has been modified to an earlier time. + // The timer has been modified to a different time. // The new when value is in the nextwhen field. - // The timer is in some P's heap, possibly in the wrong place. - timerModifiedEarlier - - // The timer has been modified to the same or a later time. - // The new when value is in the nextwhen field. - // The timer is in some P's heap, possibly in the wrong place. - timerModifiedLater + // The timer is in some P's heap, possibly in the wrong place + // (the right place by .when; the wrong place by .nextwhen). + timerModified // The timer has been modified and is being moved. // The timer will only have this status briefly. @@ -272,7 +267,7 @@ func doaddtimer(pp *p, t *timer) { func deltimer(t *timer) bool { for { switch s := t.status.Load(); s { - case timerWaiting, timerModifiedLater: + case timerWaiting, timerModified: // Prevent preemption while the timer is in timerModifying. // This could lead to a self-deadlock. See #38070. mp := acquirem() @@ -291,24 +286,6 @@ func deltimer(t *timer) bool { } else { releasem(mp) } - case timerModifiedEarlier: - // Prevent preemption while the timer is in timerModifying. - // This could lead to a self-deadlock. See #38070. - mp := acquirem() - if t.status.CompareAndSwap(s, timerModifying) { - // Must fetch t.pp before setting status - // to timerDeleted. - tpp := t.pp.ptr() - if !t.status.CompareAndSwap(timerModifying, timerDeleted) { - badTimer() - } - releasem(mp) - tpp.deletedTimers.Add(1) - // Timer was not yet run. - return true - } else { - releasem(mp) - } case timerDeleted, timerRemoving, timerRemoved: // Timer was already run. return false @@ -375,7 +352,7 @@ func modtimer(t *timer, when, period int64, f func(any, uintptr), arg any, seq u loop: for { switch status = t.status.Load(); status { - case timerWaiting, timerModifiedEarlier, timerModifiedLater: + case timerWaiting, timerModified: // Prevent preemption while the timer is in timerModifying. // This could lead to a self-deadlock. See #38070. mp = acquirem() @@ -442,26 +419,19 @@ loop: // nextwhen field, and let the other P set the when field // when it is prepared to resort the heap. t.nextwhen = when - - newStatus := uint32(timerModifiedLater) - if when < t.when { - newStatus = timerModifiedEarlier - } - - tpp := t.pp.ptr() - - if newStatus == timerModifiedEarlier { - updateTimerModifiedEarliest(tpp, when) + earlier := when < t.when + if earlier { + updateTimerModifiedEarliest(t.pp.ptr(), when) } // Set the new status of the timer. - if !t.status.CompareAndSwap(timerModifying, newStatus) { + if !t.status.CompareAndSwap(timerModifying, timerModified) { badTimer() } releasem(mp) // If the new status is earlier, wake up the poller. - if newStatus == timerModifiedEarlier { + if earlier { wakeNetPoller(when) } } @@ -509,7 +479,7 @@ func cleantimers(pp *p) { badTimer() } pp.deletedTimers.Add(-1) - case timerModifiedEarlier, timerModifiedLater: + case timerModified: if !t.status.CompareAndSwap(s, timerMoving) { continue } @@ -568,7 +538,7 @@ func moveTimers(pp *p, timers []*timer) { badTimer() } break loop - case timerModifiedEarlier, timerModifiedLater: + case timerModified: if !t.status.CompareAndSwap(s, timerMoving) { continue } @@ -609,7 +579,7 @@ func moveTimers(pp *p, timers []*timer) { // it also moves timers that have been modified to run later, // and removes deleted timers. The caller must have locked the timers for pp. func adjusttimers(pp *p, now int64, force bool) { - // If we haven't yet reached the time of the first timerModifiedEarlier + // If we haven't yet reached the time of the earliest timerModified // timer, don't do anything. This speeds up programs that adjust // a lot of timers back and forth if the timers rarely expire. // We'll postpone looking through all the adjusted timers until @@ -624,7 +594,7 @@ func adjusttimers(pp *p, now int64, force bool) { } } - // We are going to clear all timerModifiedEarlier timers. + // We are going to clear all timerModified timers. pp.timerModifiedEarliest.Store(0) changed := false @@ -648,7 +618,7 @@ func adjusttimers(pp *p, now int64, force bool) { i-- changed = true } - case timerModifiedEarlier, timerModifiedLater: + case timerModified: if t.status.CompareAndSwap(s, timerMoving) { // Now we can change the when field. t.when = t.nextwhen @@ -800,7 +770,7 @@ func runtimer(pp *p, now int64) int64 { return -1 } - case timerModifiedEarlier, timerModifiedLater: + case timerModified: if !t.status.CompareAndSwap(s, timerMoving) { continue } |
