Skip to content

Commit eff3c1e

Browse files
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Michael Knyszek <[email protected]>
1 parent 4be6b4a commit eff3c1e

File tree

1 file changed

+54
-1
lines changed

1 file changed

+54
-1
lines changed

src/runtime/time.go

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,16 @@ type timersBucket struct {
141141
// timerRemoving -> wait until status changes
142142
// timerDeleted -> panic: concurrent modtimer/deltimer calls
143143
// timerModifying -> panic: concurrent modtimer calls
144+
// resettimer:
145+
// timerNoStatus -> timerWaiting
146+
// timerRemoved -> timerWaiting
147+
// timerDeleted -> timerModifying -> timerModifiedXX
148+
// timerRemoving -> wait until status changes
149+
// timerRunning -> wait until status changes
150+
// timerWaiting -> panic: resettimer called on active timer
151+
// timerMoving -> panic: resettimer called on active timer
152+
// timerModifiedXX -> panic: resettimer called on active timer
153+
// timerModifying -> panic: resettimer called on active timer
144154

145155
// Values for the timer status field.
146156
const (
@@ -573,7 +583,50 @@ func resettimer(t *timer, when int64) {
573583
resettimerOld(t, when)
574584
return
575585
}
576-
throw("new resettimer not yet implemented")
586+
587+
if when < 0 {
588+
when = maxWhen
589+
}
590+
591+
for {
592+
switch s := atomic.Load(&t.status); s {
593+
case timerNoStatus, timerRemoved:
594+
atomic.Store(&t.status, timerWaiting)
595+
t.when = when
596+
addInitializedTimer(t)
597+
return
598+
case timerDeleted:
599+
if atomic.Cas(&t.status, s, timerModifying) {
600+
t.nextwhen = when
601+
newStatus := uint32(timerModifiedLater)
602+
if when < t.when {
603+
newStatus = timerModifiedEarlier
604+
atomic.Xadd(&t.pp.ptr().adjustTimers, 1)
605+
}
606+
if !atomic.Cas(&t.status, timerModifying, newStatus) {
607+
badTimer()
608+
}
609+
if newStatus == timerModifiedEarlier {
610+
wakeNetPoller(when)
611+
}
612+
return
613+
}
614+
case timerRemoving:
615+
// Wait for the removal to complete.
616+
osyield()
617+
case timerRunning:
618+
// Even though the timer should not be active,
619+
// we can see timerRunning if the timer function
620+
// permits some other goroutine to call resettimer.
621+
// Wait until the run is complete.
622+
osyield()
623+
case timerWaiting, timerModifying, timerModifiedEarlier, timerModifiedLater, timerMoving:
624+
// Called resettimer on active timer.
625+
badTimer()
626+
default:
627+
badTimer()
628+
}
629+
}
577630
}
578631

579632
func resettimerOld(t *timer, when int64) {

0 commit comments

Comments
 (0)