//
// deltimer:
// timerWaiting -> timerModifying -> timerDeleted
-// timerModifiedEarlier -> timerModifying -> timerDeleted
-// timerModifiedLater -> timerModifying -> timerDeleted
+// timerModified -> timerModifying -> timerDeleted
// timerNoStatus -> do nothing
// timerDeleted -> do nothing
// timerRemoving -> do nothing
// 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
// 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.
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()
} 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
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()
// 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)
}
}
badTimer()
}
pp.deletedTimers.Add(-1)
- case timerModifiedEarlier, timerModifiedLater:
+ case timerModified:
if !t.status.CompareAndSwap(s, timerMoving) {
continue
}
badTimer()
}
break loop
- case timerModifiedEarlier, timerModifiedLater:
+ case timerModified:
if !t.status.CompareAndSwap(s, timerMoving) {
continue
}
// 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
}
}
- // We are going to clear all timerModifiedEarlier timers.
+ // We are going to clear all timerModified timers.
pp.timerModifiedEarliest.Store(0)
changed := false
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
return -1
}
- case timerModifiedEarlier, timerModifiedLater:
+ case timerModified:
if !t.status.CompareAndSwap(s, timerMoving) {
continue
}