// timerModified -> timerModifying -> timerDeleted
// timerNoStatus -> do nothing
// timerDeleted -> do nothing
-// timerRemoving -> do nothing
// timerRemoved -> do nothing
// timerRunning -> wait until status changes
// timerMoving -> wait until status changes
// 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
+// timerDeleted -> timerModifying -> timerRemoved
// timerModified -> timerMoving -> timerWaiting
// runtimer (looks in P's timer heap):
// timerNoStatus -> panic: uninitialized timer
// timerWaiting -> timerRunning -> timerWaiting
// timerModifying -> wait until status changes
// timerModified -> timerMoving -> timerWaiting
-// timerDeleted -> timerRemoving -> timerRemoved
+// timerDeleted -> timerModifying -> timerRemoved
// timerRunning -> panic: concurrent runtimer calls
-// timerRemoved -> panic: inconsistent timer heap
-// timerRemoving -> panic: inconsistent timer heap
// timerMoving -> panic: inconsistent timer heap
// Values for the timer status field.
// It should not be run, but it is still in some P's heap.
timerDeleted
- // The timer is being removed.
- // The timer will only have this status briefly.
- timerRemoving
-
// The timer has been stopped.
// It is not in any P's heap.
timerRemoved
} else {
releasem(mp)
}
- case timerDeleted, timerRemoving, timerRemoved:
+ case timerDeleted, timerRemoved:
// Timer was already run.
return false
- case timerRunning, timerMoving:
- // The timer is being run or moved, by a different P.
+ case timerRunning, timerMoving, timerModifying:
+ // The timer is being run or modified, by a different P.
// Wait for it to complete.
osyield()
case timerNoStatus:
// Removing timer that was never added or
// has already been run. Also see issue 21874.
return false
- case timerModifying:
- // Simultaneous calls to deltimer and modtimer.
- // Wait for the other call to complete.
- osyield()
default:
badTimer()
}
break loop
}
releasem(mp)
- case timerRunning, timerRemoving, timerMoving:
+ case timerRunning, timerMoving:
// The timer is being run or moved, by a different P.
// Wait for it to complete.
osyield()
}
switch s := t.status.Load(); s {
case timerDeleted:
- if !t.status.CompareAndSwap(s, timerRemoving) {
+ if !t.status.CompareAndSwap(s, timerModifying) {
continue
}
dodeltimer0(pp)
- if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
+ if !t.status.CompareAndSwap(timerModifying, timerRemoved) {
badTimer()
}
pp.deletedTimers.Add(-1)
case timerNoStatus, timerRemoved:
// We should not see these status values in a timers heap.
badTimer()
- case timerRunning, timerRemoving, timerMoving:
+ case timerRunning, timerMoving:
// Some other P thinks it owns this timer,
// which should not happen.
badTimer()
}
switch s := t.status.Load(); s {
case timerDeleted:
- if t.status.CompareAndSwap(s, timerRemoving) {
+ if t.status.CompareAndSwap(s, timerModifying) {
n := len(pp.timers)
pp.timers[i] = pp.timers[n-1]
pp.timers[n-1] = nil
pp.timers = pp.timers[:n-1]
t.pp = 0
- if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
+ if !t.status.CompareAndSwap(timerModifying, timerRemoved) {
badTimer()
}
pp.deletedTimers.Add(-1)
badTimer()
}
}
- case timerNoStatus, timerRunning, timerRemoving, timerRemoved, timerMoving:
+ case timerNoStatus, timerRunning, timerRemoved, timerMoving:
badTimer()
case timerWaiting:
// OK, nothing to do.
return 0
case timerDeleted:
- if !t.status.CompareAndSwap(s, timerRemoving) {
+ if !t.status.CompareAndSwap(s, timerModifying) {
continue
}
dodeltimer0(pp)
- if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
+ if !t.status.CompareAndSwap(timerModifying, timerRemoved) {
badTimer()
}
pp.deletedTimers.Add(-1)
case timerNoStatus, timerRemoved:
// Should not see a new or inactive timer on the heap.
badTimer()
- case timerRunning, timerRemoving, timerMoving:
+ case timerRunning, timerMoving:
// These should only be set when timers are locked,
// and we didn't do it.
badTimer()