mirror of
https://github.com/golang/go
synced 2024-11-17 01:44:52 -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:
|
// deltimer:
|
||||||
// timerWaiting -> timerModifying -> timerDeleted
|
// timerWaiting -> timerModifying -> timerDeleted
|
||||||
// timerModified -> timerModifying -> timerDeleted
|
// timerModified -> timerModifying -> timerDeleted
|
||||||
// timerNoStatus -> do nothing
|
|
||||||
// timerDeleted -> do nothing
|
// timerDeleted -> do nothing
|
||||||
// timerRemoved -> do nothing
|
// timerRemoved -> do nothing
|
||||||
// timerRunning -> wait until status changes
|
// timerRunning -> wait until status changes
|
||||||
@ -81,7 +80,6 @@ type timer struct {
|
|||||||
// modtimer:
|
// modtimer:
|
||||||
// timerWaiting -> timerModifying -> timerModified
|
// timerWaiting -> timerModifying -> timerModified
|
||||||
// timerModified -> timerModifying -> timerModified
|
// timerModified -> timerModifying -> timerModified
|
||||||
// timerNoStatus -> timerModifying -> timerWaiting
|
|
||||||
// timerRemoved -> timerModifying -> timerWaiting
|
// timerRemoved -> timerModifying -> timerWaiting
|
||||||
// timerDeleted -> timerModifying -> timerModified
|
// timerDeleted -> timerModifying -> timerModified
|
||||||
// timerRunning -> wait until status changes
|
// timerRunning -> wait until status changes
|
||||||
@ -90,9 +88,9 @@ type timer struct {
|
|||||||
// timerDeleted -> timerModifying -> timerRemoved
|
// timerDeleted -> timerModifying -> timerRemoved
|
||||||
// timerModified -> timerModifying -> timerWaiting
|
// timerModified -> timerModifying -> timerWaiting
|
||||||
// runtimer (looks in P's timer heap):
|
// runtimer (looks in P's timer heap):
|
||||||
// timerNoStatus -> panic: uninitialized timer
|
// timerRemoved -> panic: uninitialized timer
|
||||||
// timerWaiting -> timerWaiting or
|
// timerWaiting -> timerWaiting or
|
||||||
// timerWaiting -> timerRunning -> timerNoStatus or
|
// timerWaiting -> timerRunning -> timerRemoved or
|
||||||
// timerWaiting -> timerRunning -> timerWaiting
|
// timerWaiting -> timerRunning -> timerWaiting
|
||||||
// timerModifying -> wait until status changes
|
// timerModifying -> wait until status changes
|
||||||
// timerModified -> timerModifying -> timerWaiting
|
// timerModified -> timerModifying -> timerWaiting
|
||||||
@ -101,8 +99,9 @@ type timer struct {
|
|||||||
|
|
||||||
// Values for the timer status field.
|
// Values for the timer status field.
|
||||||
const (
|
const (
|
||||||
// Timer has no status set yet.
|
// Timer has no status set yet or is removed from the heap.
|
||||||
timerNoStatus = iota
|
// Must be zero value; see issue 21874.
|
||||||
|
timerRemoved = iota
|
||||||
|
|
||||||
// Waiting for timer to fire.
|
// Waiting for timer to fire.
|
||||||
// The timer is in some P's heap.
|
// 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.
|
// It should not be run, but it is still in some P's heap.
|
||||||
timerDeleted
|
timerDeleted
|
||||||
|
|
||||||
// The timer has been stopped.
|
|
||||||
// It is not in any P's heap.
|
|
||||||
timerRemoved
|
|
||||||
|
|
||||||
// The timer is being modified.
|
// The timer is being modified.
|
||||||
// The timer will only have this status briefly.
|
// The timer will only have this status briefly.
|
||||||
timerModifying
|
timerModifying
|
||||||
@ -183,7 +178,7 @@ func startTimer(t *timer) {
|
|||||||
if raceenabled {
|
if raceenabled {
|
||||||
racerelease(unsafe.Pointer(t))
|
racerelease(unsafe.Pointer(t))
|
||||||
}
|
}
|
||||||
if t.status.Load() != timerNoStatus {
|
if t.status.Load() != 0 {
|
||||||
throw("startTimer called with initialized timer")
|
throw("startTimer called with initialized timer")
|
||||||
}
|
}
|
||||||
resettimer(t, t.when)
|
resettimer(t, t.when)
|
||||||
@ -278,10 +273,6 @@ func deltimer(t *timer) bool {
|
|||||||
// 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()
|
||||||
case timerNoStatus:
|
|
||||||
// Removing timer that was never added or
|
|
||||||
// has already been run. Also see issue 21874.
|
|
||||||
return false
|
|
||||||
default:
|
default:
|
||||||
badTimer()
|
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")
|
throw("timer period must be non-negative")
|
||||||
}
|
}
|
||||||
|
|
||||||
status := uint32(timerNoStatus)
|
status := uint32(timerRemoved)
|
||||||
wasRemoved := false
|
wasRemoved := false
|
||||||
var pending bool
|
var pending bool
|
||||||
var mp *m
|
var mp *m
|
||||||
@ -342,7 +333,7 @@ loop:
|
|||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
releasem(mp)
|
releasem(mp)
|
||||||
case timerNoStatus, timerRemoved:
|
case timerRemoved:
|
||||||
// Prevent preemption while the timer is in timerModifying.
|
// Prevent preemption while the timer is in timerModifying.
|
||||||
// This could lead to a self-deadlock. See #38070.
|
// This could lead to a self-deadlock. See #38070.
|
||||||
mp = acquirem()
|
mp = acquirem()
|
||||||
@ -536,7 +527,7 @@ func moveTimers(pp *p, timers []*timer) {
|
|||||||
case timerModifying:
|
case timerModifying:
|
||||||
// Loop until the modification is complete.
|
// Loop until the modification is complete.
|
||||||
osyield()
|
osyield()
|
||||||
case timerNoStatus, timerRemoved:
|
case 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:
|
case timerRunning:
|
||||||
@ -604,7 +595,7 @@ func adjusttimers(pp *p, now int64, force bool) {
|
|||||||
badTimer()
|
badTimer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case timerNoStatus, timerRunning, timerRemoved:
|
case timerRunning, timerRemoved:
|
||||||
badTimer()
|
badTimer()
|
||||||
case timerWaiting:
|
case timerWaiting:
|
||||||
// OK, nothing to do.
|
// OK, nothing to do.
|
||||||
@ -762,7 +753,7 @@ func runtimer(pp *p, now int64) int64 {
|
|||||||
// Wait for modification to complete.
|
// Wait for modification to complete.
|
||||||
osyield()
|
osyield()
|
||||||
|
|
||||||
case timerNoStatus, timerRemoved:
|
case 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:
|
case timerRunning:
|
||||||
@ -808,7 +799,7 @@ func runOneTimer(pp *p, t *timer, now int64) {
|
|||||||
} else {
|
} else {
|
||||||
// Remove from heap.
|
// Remove from heap.
|
||||||
dodeltimer0(pp)
|
dodeltimer0(pp)
|
||||||
if !t.status.CompareAndSwap(timerRunning, timerNoStatus) {
|
if !t.status.CompareAndSwap(timerRunning, timerRemoved) {
|
||||||
badTimer()
|
badTimer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user