mirror of
https://github.com/golang/go
synced 2024-11-16 22:54:47 -07:00
runtime: merge timerNoStatus into timerRemoved
For historical reasons, we have to treat a zero timer as the same as an initialized timer that was stopped (removed). The two states are already treated mostly identically. 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: I9c3aeb8f92bafb18c47489c1ec20a7b87ac5cd9c Reviewed-on: https://go-review.googlesource.com/c/go/+/564122 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
parent
3be36e9b20
commit
ed0ad591d3
@ -73,7 +73,6 @@ type timer struct {
|
||||
// deltimer:
|
||||
// timerWaiting -> timerModifying -> timerDeleted
|
||||
// timerModified -> timerModifying -> timerDeleted
|
||||
// timerNoStatus -> do nothing
|
||||
// timerDeleted -> do nothing
|
||||
// timerRemoved -> do nothing
|
||||
// timerRunning -> wait until status changes
|
||||
@ -81,7 +80,6 @@ type timer struct {
|
||||
// modtimer:
|
||||
// timerWaiting -> timerModifying -> timerModified
|
||||
// timerModified -> timerModifying -> timerModified
|
||||
// timerNoStatus -> timerModifying -> timerWaiting
|
||||
// timerRemoved -> timerModifying -> timerWaiting
|
||||
// timerDeleted -> timerModifying -> timerModified
|
||||
// timerRunning -> wait until status changes
|
||||
@ -90,9 +88,9 @@ type timer struct {
|
||||
// timerDeleted -> timerModifying -> timerRemoved
|
||||
// timerModified -> timerModifying -> timerWaiting
|
||||
// runtimer (looks in P's timer heap):
|
||||
// timerNoStatus -> panic: uninitialized timer
|
||||
// timerRemoved -> panic: uninitialized timer
|
||||
// timerWaiting -> timerWaiting or
|
||||
// timerWaiting -> timerRunning -> timerNoStatus or
|
||||
// timerWaiting -> timerRunning -> timerRemoved or
|
||||
// timerWaiting -> timerRunning -> timerWaiting
|
||||
// timerModifying -> wait until status changes
|
||||
// timerModified -> timerModifying -> timerWaiting
|
||||
@ -101,8 +99,9 @@ type timer struct {
|
||||
|
||||
// Values for the timer status field.
|
||||
const (
|
||||
// Timer has no status set yet.
|
||||
timerNoStatus = iota
|
||||
// Timer has no status set yet or is removed from the heap.
|
||||
// Must be zero value; see issue 21874.
|
||||
timerRemoved = iota
|
||||
|
||||
// Waiting for timer to fire.
|
||||
// The timer is in some P's heap.
|
||||
@ -116,10 +115,6 @@ const (
|
||||
// It should not be run, but it is still in some P's heap.
|
||||
timerDeleted
|
||||
|
||||
// The timer has been stopped.
|
||||
// It is not in any P's heap.
|
||||
timerRemoved
|
||||
|
||||
// The timer is being modified.
|
||||
// The timer will only have this status briefly.
|
||||
timerModifying
|
||||
@ -183,7 +178,7 @@ func startTimer(t *timer) {
|
||||
if raceenabled {
|
||||
racerelease(unsafe.Pointer(t))
|
||||
}
|
||||
if t.status.Load() != timerNoStatus {
|
||||
if t.status.Load() != 0 {
|
||||
throw("startTimer called with initialized timer")
|
||||
}
|
||||
resettimer(t, t.when)
|
||||
@ -278,10 +273,6 @@ func deltimer(t *timer) bool {
|
||||
// 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
|
||||
default:
|
||||
badTimer()
|
||||
}
|
||||
@ -326,7 +317,7 @@ func modtimer(t *timer, when, period int64, f func(any, uintptr), arg any, seq u
|
||||
throw("timer period must be non-negative")
|
||||
}
|
||||
|
||||
status := uint32(timerNoStatus)
|
||||
status := uint32(timerRemoved)
|
||||
wasRemoved := false
|
||||
var pending bool
|
||||
var mp *m
|
||||
@ -342,7 +333,7 @@ loop:
|
||||
break loop
|
||||
}
|
||||
releasem(mp)
|
||||
case timerNoStatus, timerRemoved:
|
||||
case timerRemoved:
|
||||
// Prevent preemption while the timer is in timerModifying.
|
||||
// This could lead to a self-deadlock. See #38070.
|
||||
mp = acquirem()
|
||||
@ -536,7 +527,7 @@ func moveTimers(pp *p, timers []*timer) {
|
||||
case timerModifying:
|
||||
// Loop until the modification is complete.
|
||||
osyield()
|
||||
case timerNoStatus, timerRemoved:
|
||||
case timerRemoved:
|
||||
// We should not see these status values in a timers heap.
|
||||
badTimer()
|
||||
case timerRunning:
|
||||
@ -604,7 +595,7 @@ func adjusttimers(pp *p, now int64, force bool) {
|
||||
badTimer()
|
||||
}
|
||||
}
|
||||
case timerNoStatus, timerRunning, timerRemoved:
|
||||
case timerRunning, timerRemoved:
|
||||
badTimer()
|
||||
case timerWaiting:
|
||||
// OK, nothing to do.
|
||||
@ -762,7 +753,7 @@ func runtimer(pp *p, now int64) int64 {
|
||||
// Wait for modification to complete.
|
||||
osyield()
|
||||
|
||||
case timerNoStatus, timerRemoved:
|
||||
case timerRemoved:
|
||||
// Should not see a new or inactive timer on the heap.
|
||||
badTimer()
|
||||
case timerRunning:
|
||||
@ -808,7 +799,7 @@ func runOneTimer(pp *p, t *timer, now int64) {
|
||||
} else {
|
||||
// Remove from heap.
|
||||
dodeltimer0(pp)
|
||||
if !t.status.CompareAndSwap(timerRunning, timerNoStatus) {
|
||||
if !t.status.CompareAndSwap(timerRunning, timerRemoved) {
|
||||
badTimer()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user