aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/time.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2019-04-10 21:46:12 -0700
committerIan Lance Taylor <iant@golang.org>2019-10-22 21:23:03 +0000
commit7d891d5e4d7bd7d22b6adcc51e10c9be01825c16 (patch)
treea22fab142dd2034f315281b1a8274d4492cc7500 /src/runtime/time.go
parent466547014769bbdf7d5a62ca1019bf52d809dfcd (diff)
downloadgo-7d891d5e4d7bd7d22b6adcc51e10c9be01825c16.tar.gz
go-7d891d5e4d7bd7d22b6adcc51e10c9be01825c16.zip
runtime: implement new movetimers function
Updates #27707 Change-Id: Idda31d0065064a81c570e291ef588d020871997d Reviewed-on: https://go-review.googlesource.com/c/go/+/171836 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/runtime/time.go')
-rw-r--r--src/runtime/time.go46
1 files changed, 45 insertions, 1 deletions
diff --git a/src/runtime/time.go b/src/runtime/time.go
index ffb56f1805..e206a68650 100644
--- a/src/runtime/time.go
+++ b/src/runtime/time.go
@@ -816,7 +816,51 @@ func cleantimers(pp *p) bool {
// This is currently called when the world is stopped, but it could
// work as long as the timers for pp are locked.
func moveTimers(pp *p, timers []*timer) {
- throw("movetimers: not yet implemented")
+ for _, t := range timers {
+ loop:
+ for {
+ switch s := atomic.Load(&t.status); s {
+ case timerWaiting:
+ t.pp = 0
+ if !doaddtimer(pp, t) {
+ badTimer()
+ }
+ break loop
+ case timerModifiedEarlier, timerModifiedLater:
+ if !atomic.Cas(&t.status, s, timerMoving) {
+ continue
+ }
+ t.when = t.nextwhen
+ t.pp = 0
+ if !doaddtimer(pp, t) {
+ badTimer()
+ }
+ if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
+ badTimer()
+ }
+ break loop
+ case timerDeleted:
+ if !atomic.Cas(&t.status, s, timerRemoved) {
+ continue
+ }
+ t.pp = 0
+ // We no longer need this timer in the heap.
+ break loop
+ case timerModifying:
+ // Loop until the modification is complete.
+ osyield()
+ case timerNoStatus, timerRemoved:
+ // We should not see these status values in a timers heap.
+ badTimer()
+ case timerRunning, timerRemoving, timerMoving:
+ // Some other P thinks it owns this timer,
+ // which should not happen.
+ badTimer()
+ default:
+ badTimer()
+ }
+ }
+ }
}
// adjusttimers looks through the timers in the current P's heap for