aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/time.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2019-11-05 07:24:18 -0800
committerIan Lance Taylor <iant@golang.org>2019-11-05 18:37:06 +0000
commitc3cef0bfe5f503ee016fc61e58f5ee1b78dbd962 (patch)
tree828d3cadc8c5ac7972044aad290a393b454009e3 /src/runtime/time.go
parenta9c0cc6f6744654de7f8fdff52f5da601a109d11 (diff)
downloadgo-c3cef0bfe5f503ee016fc61e58f5ee1b78dbd962.tar.gz
go-c3cef0bfe5f503ee016fc61e58f5ee1b78dbd962.zip
runtime: keep adjusted timers in timerMoving status until moved
Before this CL adjustTimers left timers being moved in an inconsistent state: status timerWaiting but not on a P. Simplify the code by leaving the timers in timerMoving status until they are actually moved. Other functions (deltimer, modtimer) will wait until the move is complete before changing anything on the timer. This does leave timers in timerMoving state for longer, but still not all that long. Fixes #35367 Change-Id: I31851002fb4053bd6914139125b4c82a68bf6fb2 Reviewed-on: https://go-review.googlesource.com/c/go/+/205418 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/runtime/time.go')
-rw-r--r--src/runtime/time.go49
1 files changed, 5 insertions, 44 deletions
diff --git a/src/runtime/time.go b/src/runtime/time.go
index 6ae5225c68..ad5eaf7c48 100644
--- a/src/runtime/time.go
+++ b/src/runtime/time.go
@@ -947,9 +947,6 @@ func adjusttimers(pp *p) {
badTimer()
}
moved = append(moved, t)
- if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
- badTimer()
- }
if s == timerModifiedEarlier {
if n := atomic.Xadd(&pp.adjustTimers, -1); int32(n) <= 0 {
addAdjustedTimers(pp, moved)
@@ -979,47 +976,11 @@ func adjusttimers(pp *p) {
// back to the timer heap.
func addAdjustedTimers(pp *p, moved []*timer) {
for _, t := range moved {
- loop:
- for {
- switch s := atomic.Load(&t.status); s {
- case timerWaiting:
- // This is the normal case.
- if !doaddtimer(pp, t) {
- badTimer()
- }
- break loop
- case timerDeleted:
- // Timer has been deleted since we adjusted it.
- // This timer is already out of the heap.
- if atomic.Cas(&t.status, s, timerRemoving) {
- if !atomic.Cas(&t.status, timerRemoving, timerRemoved) {
- badTimer()
- }
- break loop
- }
- case timerModifiedEarlier, timerModifiedLater:
- // Timer has been modified again since
- // we adjusted it.
- if atomic.Cas(&t.status, s, timerMoving) {
- t.when = t.nextwhen
- if !doaddtimer(pp, t) {
- badTimer()
- }
- if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
- badTimer()
- }
- if s == timerModifiedEarlier {
- atomic.Xadd(&pp.adjustTimers, -1)
- }
- break loop
- }
- case timerNoStatus, timerRunning, timerRemoving, timerRemoved, timerMoving:
- badTimer()
- case timerModifying:
- // Wait and try again.
- osyield()
- continue
- }
+ if !doaddtimer(pp, t) {
+ badTimer()
+ }
+ if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
+ badTimer()
}
}
}