]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: implement new movetimers function
authorIan Lance Taylor <iant@golang.org>
Thu, 11 Apr 2019 04:46:12 +0000 (21:46 -0700)
committerIan Lance Taylor <iant@golang.org>
Tue, 22 Oct 2019 21:23:03 +0000 (21:23 +0000)
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>
src/runtime/time.go

index ffb56f1805538b64cd1d8699bba3c3909948c942..e206a6865051440a88a01aa05d540fbb7552e0ef 100644 (file)
@@ -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