1
0
mirror of https://github.com/golang/go synced 2024-11-23 21:00:06 -07:00

runtime: add new resettimer function

Updates #27707

Change-Id: I02f97ec7869ec8a3fb2dfc94cff246badc7ea0fa
Reviewed-on: https://go-review.googlesource.com/c/go/+/171833
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
Ian Lance Taylor 2019-04-10 21:16:09 -07:00
parent 4be6b4a73d
commit eff3c1e426

View File

@ -141,6 +141,16 @@ type timersBucket struct {
// timerRemoving -> wait until status changes // timerRemoving -> wait until status changes
// timerDeleted -> panic: concurrent modtimer/deltimer calls // timerDeleted -> panic: concurrent modtimer/deltimer calls
// timerModifying -> panic: concurrent modtimer calls // timerModifying -> panic: concurrent modtimer calls
// resettimer:
// timerNoStatus -> timerWaiting
// timerRemoved -> timerWaiting
// timerDeleted -> timerModifying -> timerModifiedXX
// timerRemoving -> wait until status changes
// timerRunning -> wait until status changes
// timerWaiting -> panic: resettimer called on active timer
// timerMoving -> panic: resettimer called on active timer
// timerModifiedXX -> panic: resettimer called on active timer
// timerModifying -> panic: resettimer called on active timer
// Values for the timer status field. // Values for the timer status field.
const ( const (
@ -573,7 +583,50 @@ func resettimer(t *timer, when int64) {
resettimerOld(t, when) resettimerOld(t, when)
return return
} }
throw("new resettimer not yet implemented")
if when < 0 {
when = maxWhen
}
for {
switch s := atomic.Load(&t.status); s {
case timerNoStatus, timerRemoved:
atomic.Store(&t.status, timerWaiting)
t.when = when
addInitializedTimer(t)
return
case timerDeleted:
if atomic.Cas(&t.status, s, timerModifying) {
t.nextwhen = when
newStatus := uint32(timerModifiedLater)
if when < t.when {
newStatus = timerModifiedEarlier
atomic.Xadd(&t.pp.ptr().adjustTimers, 1)
}
if !atomic.Cas(&t.status, timerModifying, newStatus) {
badTimer()
}
if newStatus == timerModifiedEarlier {
wakeNetPoller(when)
}
return
}
case timerRemoving:
// Wait for the removal to complete.
osyield()
case timerRunning:
// Even though the timer should not be active,
// we can see timerRunning if the timer function
// permits some other goroutine to call resettimer.
// Wait until the run is complete.
osyield()
case timerWaiting, timerModifying, timerModifiedEarlier, timerModifiedLater, timerMoving:
// Called resettimer on active timer.
badTimer()
default:
badTimer()
}
}
} }
func resettimerOld(t *timer, when int64) { func resettimerOld(t *timer, when int64) {