diff options
author | Ian Lance Taylor <iant@golang.org> | 2019-04-10 21:46:12 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2019-10-22 21:23:03 +0000 |
commit | 7d891d5e4d7bd7d22b6adcc51e10c9be01825c16 (patch) | |
tree | a22fab142dd2034f315281b1a8274d4492cc7500 /src/runtime/time.go | |
parent | 466547014769bbdf7d5a62ca1019bf52d809dfcd (diff) | |
download | go-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.go | 46 |
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 |