github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/runtime/time.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Time-related runtime and pieces of package time. 6 7 package runtime 8 9 import ( 10 "runtime/internal/atomic" 11 "runtime/internal/sys" 12 "unsafe" 13 ) 14 15 // Package time knows the layout of this structure. 16 // If this struct changes, adjust ../time/sleep.go:/runtimeTimer. 17 type timer struct { 18 // If this timer is on a heap, which P's heap it is on. 19 // puintptr rather than *p to match uintptr in the versions 20 // of this struct defined in other packages. 21 pp puintptr 22 23 // Timer wakes up at when, and then at when+period, ... (period > 0 only) 24 // each time calling f(arg, now) in the timer goroutine, so f must be 25 // a well-behaved function and not block. 26 // 27 // when must be positive on an active timer. 28 when int64 29 period int64 30 f func(interface{}, uintptr) 31 arg interface{} 32 seq uintptr 33 34 // What to set the when field to in timerModifiedXX status. 35 nextwhen int64 36 37 // The status field holds one of the values below. 38 status uint32 39 } 40 41 // Code outside this file has to be careful in using a timer value. 42 // 43 // The pp, status, and nextwhen fields may only be used by code in this file. 44 // 45 // Code that creates a new timer value can set the when, period, f, 46 // arg, and seq fields. 47 // A new timer value may be passed to addtimer (called by time.startTimer). 48 // After doing that no fields may be touched. 49 // 50 // An active timer (one that has been passed to addtimer) may be 51 // passed to deltimer (time.stopTimer), after which it is no longer an 52 // active timer. It is an inactive timer. 53 // In an inactive timer the period, f, arg, and seq fields may be modified, 54 // but not the when field. 55 // It's OK to just drop an inactive timer and let the GC collect it. 56 // It's not OK to pass an inactive timer to addtimer. 57 // Only newly allocated timer values may be passed to addtimer. 58 // 59 // An active timer may be passed to modtimer. No fields may be touched. 60 // It remains an active timer. 61 // 62 // An inactive timer may be passed to resettimer to turn into an 63 // active timer with an updated when field. 64 // It's OK to pass a newly allocated timer value to resettimer. 65 // 66 // Timer operations are addtimer, deltimer, modtimer, resettimer, 67 // cleantimers, adjusttimers, and runtimer. 68 // 69 // We don't permit calling addtimer/deltimer/modtimer/resettimer simultaneously, 70 // but adjusttimers and runtimer can be called at the same time as any of those. 71 // 72 // Active timers live in heaps attached to P, in the timers field. 73 // Inactive timers live there too temporarily, until they are removed. 74 // 75 // addtimer: 76 // timerNoStatus -> timerWaiting 77 // anything else -> panic: invalid value 78 // deltimer: 79 // timerWaiting -> timerModifying -> timerDeleted 80 // timerModifiedEarlier -> timerModifying -> timerDeleted 81 // timerModifiedLater -> timerModifying -> timerDeleted 82 // timerNoStatus -> do nothing 83 // timerDeleted -> do nothing 84 // timerRemoving -> do nothing 85 // timerRemoved -> do nothing 86 // timerRunning -> wait until status changes 87 // timerMoving -> wait until status changes 88 // timerModifying -> wait until status changes 89 // modtimer: 90 // timerWaiting -> timerModifying -> timerModifiedXX 91 // timerModifiedXX -> timerModifying -> timerModifiedYY 92 // timerNoStatus -> timerModifying -> timerWaiting 93 // timerRemoved -> timerModifying -> timerWaiting 94 // timerDeleted -> timerModifying -> timerModifiedXX 95 // timerRunning -> wait until status changes 96 // timerMoving -> wait until status changes 97 // timerRemoving -> wait until status changes 98 // timerModifying -> wait until status changes 99 // cleantimers (looks in P's timer heap): 100 // timerDeleted -> timerRemoving -> timerRemoved 101 // timerModifiedXX -> timerMoving -> timerWaiting 102 // adjusttimers (looks in P's timer heap): 103 // timerDeleted -> timerRemoving -> timerRemoved 104 // timerModifiedXX -> timerMoving -> timerWaiting 105 // runtimer (looks in P's timer heap): 106 // timerNoStatus -> panic: uninitialized timer 107 // timerWaiting -> timerWaiting or 108 // timerWaiting -> timerRunning -> timerNoStatus or 109 // timerWaiting -> timerRunning -> timerWaiting 110 // timerModifying -> wait until status changes 111 // timerModifiedXX -> timerMoving -> timerWaiting 112 // timerDeleted -> timerRemoving -> timerRemoved 113 // timerRunning -> panic: concurrent runtimer calls 114 // timerRemoved -> panic: inconsistent timer heap 115 // timerRemoving -> panic: inconsistent timer heap 116 // timerMoving -> panic: inconsistent timer heap 117 118 // Values for the timer status field. 119 const ( 120 // Timer has no status set yet. 121 timerNoStatus = iota 122 123 // Waiting for timer to fire. 124 // The timer is in some P's heap. 125 timerWaiting 126 127 // Running the timer function. 128 // A timer will only have this status briefly. 129 timerRunning 130 131 // The timer is deleted and should be removed. 132 // It should not be run, but it is still in some P's heap. 133 timerDeleted 134 135 // The timer is being removed. 136 // The timer will only have this status briefly. 137 timerRemoving 138 139 // The timer has been stopped. 140 // It is not in any P's heap. 141 timerRemoved 142 143 // The timer is being modified. 144 // The timer will only have this status briefly. 145 timerModifying 146 147 // The timer has been modified to an earlier time. 148 // The new when value is in the nextwhen field. 149 // The timer is in some P's heap, possibly in the wrong place. 150 timerModifiedEarlier 151 152 // The timer has been modified to the same or a later time. 153 // The new when value is in the nextwhen field. 154 // The timer is in some P's heap, possibly in the wrong place. 155 timerModifiedLater 156 157 // The timer has been modified and is being moved. 158 // The timer will only have this status briefly. 159 timerMoving 160 ) 161 162 // maxWhen is the maximum value for timer's when field. 163 const maxWhen = 1<<63 - 1 164 165 // verifyTimers can be set to true to add debugging checks that the 166 // timer heaps are valid. 167 const verifyTimers = false 168 169 // Package time APIs. 170 // Godoc uses the comments in package time, not these. 171 172 // time.now is implemented in assembly. 173 174 // timeSleep puts the current goroutine to sleep for at least ns nanoseconds. 175 //go:linkname timeSleep time.Sleep 176 func timeSleep(ns int64) { 177 if ns <= 0 { 178 return 179 } 180 181 gp := getg() 182 t := gp.timer 183 if t == nil { 184 t = new(timer) 185 gp.timer = t 186 } 187 t.f = goroutineReady 188 t.arg = gp 189 t.nextwhen = nanotime() + ns 190 if t.nextwhen < 0 { // check for overflow. 191 t.nextwhen = maxWhen 192 } 193 gopark(resetForSleep, unsafe.Pointer(t), waitReasonSleep, traceEvGoSleep, 1) 194 } 195 196 // resetForSleep is called after the goroutine is parked for timeSleep. 197 // We can't call resettimer in timeSleep itself because if this is a short 198 // sleep and there are many goroutines then the P can wind up running the 199 // timer function, goroutineReady, before the goroutine has been parked. 200 func resetForSleep(gp *g, ut unsafe.Pointer) bool { 201 t := (*timer)(ut) 202 resettimer(t, t.nextwhen) 203 return true 204 } 205 206 // startTimer adds t to the timer heap. 207 //go:linkname startTimer time.startTimer 208 func startTimer(t *timer) { 209 if raceenabled { 210 racerelease(unsafe.Pointer(t)) 211 } 212 addtimer(t) 213 } 214 215 // stopTimer stops a timer. 216 // It reports whether t was stopped before being run. 217 //go:linkname stopTimer time.stopTimer 218 func stopTimer(t *timer) bool { 219 return deltimer(t) 220 } 221 222 // resetTimer resets an inactive timer, adding it to the heap. 223 //go:linkname resetTimer time.resetTimer 224 // Reports whether the timer was modified before it was run. 225 func resetTimer(t *timer, when int64) bool { 226 if raceenabled { 227 racerelease(unsafe.Pointer(t)) 228 } 229 return resettimer(t, when) 230 } 231 232 // modTimer modifies an existing timer. 233 //go:linkname modTimer time.modTimer 234 func modTimer(t *timer, when, period int64, f func(interface{}, uintptr), arg interface{}, seq uintptr) { 235 modtimer(t, when, period, f, arg, seq) 236 } 237 238 // Go runtime. 239 240 // Ready the goroutine arg. 241 func goroutineReady(arg interface{}, seq uintptr) { 242 goready(arg.(*g), 0) 243 } 244 245 // addtimer adds a timer to the current P. 246 // This should only be called with a newly created timer. 247 // That avoids the risk of changing the when field of a timer in some P's heap, 248 // which could cause the heap to become unsorted. 249 func addtimer(t *timer) { 250 // when must be positive. A negative value will cause runtimer to 251 // overflow during its delta calculation and never expire other runtime 252 // timers. Zero will cause checkTimers to fail to notice the timer. 253 if t.when <= 0 { 254 throw("timer when must be positive") 255 } 256 if t.period < 0 { 257 throw("timer period must be non-negative") 258 } 259 if t.status != timerNoStatus { 260 throw("addtimer called with initialized timer") 261 } 262 t.status = timerWaiting 263 264 when := t.when 265 266 pp := getg().m.p.ptr() 267 lock(&pp.timersLock) 268 cleantimers(pp) 269 doaddtimer(pp, t) 270 unlock(&pp.timersLock) 271 272 wakeNetPoller(when) 273 } 274 275 // doaddtimer adds t to the current P's heap. 276 // The caller must have locked the timers for pp. 277 func doaddtimer(pp *p, t *timer) { 278 // Timers rely on the network poller, so make sure the poller 279 // has started. 280 if netpollInited == 0 { 281 netpollGenericInit() 282 } 283 284 if t.pp != 0 { 285 throw("doaddtimer: P already set in timer") 286 } 287 t.pp.set(pp) 288 i := len(pp.timers) 289 pp.timers = append(pp.timers, t) 290 siftupTimer(pp.timers, i) 291 if t == pp.timers[0] { 292 atomic.Store64(&pp.timer0When, uint64(t.when)) 293 } 294 atomic.Xadd(&pp.numTimers, 1) 295 } 296 297 // deltimer deletes the timer t. It may be on some other P, so we can't 298 // actually remove it from the timers heap. We can only mark it as deleted. 299 // It will be removed in due course by the P whose heap it is on. 300 // Reports whether the timer was removed before it was run. 301 func deltimer(t *timer) bool { 302 for { 303 switch s := atomic.Load(&t.status); s { 304 case timerWaiting, timerModifiedLater: 305 // Prevent preemption while the timer is in timerModifying. 306 // This could lead to a self-deadlock. See #38070. 307 mp := acquirem() 308 if atomic.Cas(&t.status, s, timerModifying) { 309 // Must fetch t.pp before changing status, 310 // as cleantimers in another goroutine 311 // can clear t.pp of a timerDeleted timer. 312 tpp := t.pp.ptr() 313 if !atomic.Cas(&t.status, timerModifying, timerDeleted) { 314 badTimer() 315 } 316 releasem(mp) 317 atomic.Xadd(&tpp.deletedTimers, 1) 318 // Timer was not yet run. 319 return true 320 } else { 321 releasem(mp) 322 } 323 case timerModifiedEarlier: 324 // Prevent preemption while the timer is in timerModifying. 325 // This could lead to a self-deadlock. See #38070. 326 mp := acquirem() 327 if atomic.Cas(&t.status, s, timerModifying) { 328 // Must fetch t.pp before setting status 329 // to timerDeleted. 330 tpp := t.pp.ptr() 331 atomic.Xadd(&tpp.adjustTimers, -1) 332 if !atomic.Cas(&t.status, timerModifying, timerDeleted) { 333 badTimer() 334 } 335 releasem(mp) 336 atomic.Xadd(&tpp.deletedTimers, 1) 337 // Timer was not yet run. 338 return true 339 } else { 340 releasem(mp) 341 } 342 case timerDeleted, timerRemoving, timerRemoved: 343 // Timer was already run. 344 return false 345 case timerRunning, timerMoving: 346 // The timer is being run or moved, by a different P. 347 // Wait for it to complete. 348 osyield() 349 case timerNoStatus: 350 // Removing timer that was never added or 351 // has already been run. Also see issue 21874. 352 return false 353 case timerModifying: 354 // Simultaneous calls to deltimer and modtimer. 355 // Wait for the other call to complete. 356 osyield() 357 default: 358 badTimer() 359 } 360 } 361 } 362 363 // dodeltimer removes timer i from the current P's heap. 364 // We are locked on the P when this is called. 365 // It reports whether it saw no problems due to races. 366 // The caller must have locked the timers for pp. 367 func dodeltimer(pp *p, i int) { 368 if t := pp.timers[i]; t.pp.ptr() != pp { 369 throw("dodeltimer: wrong P") 370 } else { 371 t.pp = 0 372 } 373 last := len(pp.timers) - 1 374 if i != last { 375 pp.timers[i] = pp.timers[last] 376 } 377 pp.timers[last] = nil 378 pp.timers = pp.timers[:last] 379 if i != last { 380 // Moving to i may have moved the last timer to a new parent, 381 // so sift up to preserve the heap guarantee. 382 siftupTimer(pp.timers, i) 383 siftdownTimer(pp.timers, i) 384 } 385 if i == 0 { 386 updateTimer0When(pp) 387 } 388 atomic.Xadd(&pp.numTimers, -1) 389 } 390 391 // dodeltimer0 removes timer 0 from the current P's heap. 392 // We are locked on the P when this is called. 393 // It reports whether it saw no problems due to races. 394 // The caller must have locked the timers for pp. 395 func dodeltimer0(pp *p) { 396 if t := pp.timers[0]; t.pp.ptr() != pp { 397 throw("dodeltimer0: wrong P") 398 } else { 399 t.pp = 0 400 } 401 last := len(pp.timers) - 1 402 if last > 0 { 403 pp.timers[0] = pp.timers[last] 404 } 405 pp.timers[last] = nil 406 pp.timers = pp.timers[:last] 407 if last > 0 { 408 siftdownTimer(pp.timers, 0) 409 } 410 updateTimer0When(pp) 411 atomic.Xadd(&pp.numTimers, -1) 412 } 413 414 // modtimer modifies an existing timer. 415 // This is called by the netpoll code or time.Ticker.Reset or time.Timer.Reset. 416 // Reports whether the timer was modified before it was run. 417 func modtimer(t *timer, when, period int64, f func(interface{}, uintptr), arg interface{}, seq uintptr) bool { 418 if when <= 0 { 419 throw("timer when must be positive") 420 } 421 if period < 0 { 422 throw("timer period must be non-negative") 423 } 424 425 status := uint32(timerNoStatus) 426 wasRemoved := false 427 var pending bool 428 var mp *m 429 loop: 430 for { 431 switch status = atomic.Load(&t.status); status { 432 case timerWaiting, timerModifiedEarlier, timerModifiedLater: 433 // Prevent preemption while the timer is in timerModifying. 434 // This could lead to a self-deadlock. See #38070. 435 mp = acquirem() 436 if atomic.Cas(&t.status, status, timerModifying) { 437 pending = true // timer not yet run 438 break loop 439 } 440 releasem(mp) 441 case timerNoStatus, timerRemoved: 442 // Prevent preemption while the timer is in timerModifying. 443 // This could lead to a self-deadlock. See #38070. 444 mp = acquirem() 445 446 // Timer was already run and t is no longer in a heap. 447 // Act like addtimer. 448 if atomic.Cas(&t.status, status, timerModifying) { 449 wasRemoved = true 450 pending = false // timer already run or stopped 451 break loop 452 } 453 releasem(mp) 454 case timerDeleted: 455 // Prevent preemption while the timer is in timerModifying. 456 // This could lead to a self-deadlock. See #38070. 457 mp = acquirem() 458 if atomic.Cas(&t.status, status, timerModifying) { 459 atomic.Xadd(&t.pp.ptr().deletedTimers, -1) 460 pending = false // timer already stopped 461 break loop 462 } 463 releasem(mp) 464 case timerRunning, timerRemoving, timerMoving: 465 // The timer is being run or moved, by a different P. 466 // Wait for it to complete. 467 osyield() 468 case timerModifying: 469 // Multiple simultaneous calls to modtimer. 470 // Wait for the other call to complete. 471 osyield() 472 default: 473 badTimer() 474 } 475 } 476 477 t.period = period 478 t.f = f 479 t.arg = arg 480 t.seq = seq 481 482 if wasRemoved { 483 t.when = when 484 pp := getg().m.p.ptr() 485 lock(&pp.timersLock) 486 doaddtimer(pp, t) 487 unlock(&pp.timersLock) 488 if !atomic.Cas(&t.status, timerModifying, timerWaiting) { 489 badTimer() 490 } 491 releasem(mp) 492 wakeNetPoller(when) 493 } else { 494 // The timer is in some other P's heap, so we can't change 495 // the when field. If we did, the other P's heap would 496 // be out of order. So we put the new when value in the 497 // nextwhen field, and let the other P set the when field 498 // when it is prepared to resort the heap. 499 t.nextwhen = when 500 501 newStatus := uint32(timerModifiedLater) 502 if when < t.when { 503 newStatus = timerModifiedEarlier 504 } 505 506 tpp := t.pp.ptr() 507 508 // Update the adjustTimers field. Subtract one if we 509 // are removing a timerModifiedEarlier, add one if we 510 // are adding a timerModifiedEarlier. 511 adjust := int32(0) 512 if status == timerModifiedEarlier { 513 adjust-- 514 } 515 if newStatus == timerModifiedEarlier { 516 adjust++ 517 updateTimerModifiedEarliest(tpp, when) 518 } 519 if adjust != 0 { 520 atomic.Xadd(&tpp.adjustTimers, adjust) 521 } 522 523 // Set the new status of the timer. 524 if !atomic.Cas(&t.status, timerModifying, newStatus) { 525 badTimer() 526 } 527 releasem(mp) 528 529 // If the new status is earlier, wake up the poller. 530 if newStatus == timerModifiedEarlier { 531 wakeNetPoller(when) 532 } 533 } 534 535 return pending 536 } 537 538 // resettimer resets the time when a timer should fire. 539 // If used for an inactive timer, the timer will become active. 540 // This should be called instead of addtimer if the timer value has been, 541 // or may have been, used previously. 542 // Reports whether the timer was modified before it was run. 543 func resettimer(t *timer, when int64) bool { 544 return modtimer(t, when, t.period, t.f, t.arg, t.seq) 545 } 546 547 // cleantimers cleans up the head of the timer queue. This speeds up 548 // programs that create and delete timers; leaving them in the heap 549 // slows down addtimer. Reports whether no timer problems were found. 550 // The caller must have locked the timers for pp. 551 func cleantimers(pp *p) { 552 gp := getg() 553 for { 554 if len(pp.timers) == 0 { 555 return 556 } 557 558 // This loop can theoretically run for a while, and because 559 // it is holding timersLock it cannot be preempted. 560 // If someone is trying to preempt us, just return. 561 // We can clean the timers later. 562 if gp.preemptStop { 563 return 564 } 565 566 t := pp.timers[0] 567 if t.pp.ptr() != pp { 568 throw("cleantimers: bad p") 569 } 570 switch s := atomic.Load(&t.status); s { 571 case timerDeleted: 572 if !atomic.Cas(&t.status, s, timerRemoving) { 573 continue 574 } 575 dodeltimer0(pp) 576 if !atomic.Cas(&t.status, timerRemoving, timerRemoved) { 577 badTimer() 578 } 579 atomic.Xadd(&pp.deletedTimers, -1) 580 case timerModifiedEarlier, timerModifiedLater: 581 if !atomic.Cas(&t.status, s, timerMoving) { 582 continue 583 } 584 // Now we can change the when field. 585 t.when = t.nextwhen 586 // Move t to the right position. 587 dodeltimer0(pp) 588 doaddtimer(pp, t) 589 if s == timerModifiedEarlier { 590 atomic.Xadd(&pp.adjustTimers, -1) 591 } 592 if !atomic.Cas(&t.status, timerMoving, timerWaiting) { 593 badTimer() 594 } 595 default: 596 // Head of timers does not need adjustment. 597 return 598 } 599 } 600 } 601 602 // moveTimers moves a slice of timers to pp. The slice has been taken 603 // from a different P. 604 // This is currently called when the world is stopped, but the caller 605 // is expected to have locked the timers for pp. 606 func moveTimers(pp *p, timers []*timer) { 607 for _, t := range timers { 608 loop: 609 for { 610 switch s := atomic.Load(&t.status); s { 611 case timerWaiting: 612 if !atomic.Cas(&t.status, s, timerMoving) { 613 continue 614 } 615 t.pp = 0 616 doaddtimer(pp, t) 617 if !atomic.Cas(&t.status, timerMoving, timerWaiting) { 618 badTimer() 619 } 620 break loop 621 case timerModifiedEarlier, timerModifiedLater: 622 if !atomic.Cas(&t.status, s, timerMoving) { 623 continue 624 } 625 t.when = t.nextwhen 626 t.pp = 0 627 doaddtimer(pp, t) 628 if !atomic.Cas(&t.status, timerMoving, timerWaiting) { 629 badTimer() 630 } 631 break loop 632 case timerDeleted: 633 if !atomic.Cas(&t.status, s, timerRemoved) { 634 continue 635 } 636 t.pp = 0 637 // We no longer need this timer in the heap. 638 break loop 639 case timerModifying: 640 // Loop until the modification is complete. 641 osyield() 642 case timerNoStatus, timerRemoved: 643 // We should not see these status values in a timers heap. 644 badTimer() 645 case timerRunning, timerRemoving, timerMoving: 646 // Some other P thinks it owns this timer, 647 // which should not happen. 648 badTimer() 649 default: 650 badTimer() 651 } 652 } 653 } 654 } 655 656 // adjusttimers looks through the timers in the current P's heap for 657 // any timers that have been modified to run earlier, and puts them in 658 // the correct place in the heap. While looking for those timers, 659 // it also moves timers that have been modified to run later, 660 // and removes deleted timers. The caller must have locked the timers for pp. 661 func adjusttimers(pp *p, now int64) { 662 if atomic.Load(&pp.adjustTimers) == 0 { 663 if verifyTimers { 664 verifyTimerHeap(pp) 665 } 666 // There are no timers to adjust, so it is safe to clear 667 // timerModifiedEarliest. Do so in case it is stale. 668 // Everything will work if we don't do this, 669 // but clearing here may save future calls to adjusttimers. 670 atomic.Store64(&pp.timerModifiedEarliest, 0) 671 return 672 } 673 674 // If we haven't yet reached the time of the first timerModifiedEarlier 675 // timer, don't do anything. This speeds up programs that adjust 676 // a lot of timers back and forth if the timers rarely expire. 677 // We'll postpone looking through all the adjusted timers until 678 // one would actually expire. 679 if first := atomic.Load64(&pp.timerModifiedEarliest); first != 0 { 680 if int64(first) > now { 681 if verifyTimers { 682 verifyTimerHeap(pp) 683 } 684 return 685 } 686 687 // We are going to clear all timerModifiedEarlier timers. 688 atomic.Store64(&pp.timerModifiedEarliest, 0) 689 } 690 691 var moved []*timer 692 loop: 693 for i := 0; i < len(pp.timers); i++ { 694 t := pp.timers[i] 695 if t.pp.ptr() != pp { 696 throw("adjusttimers: bad p") 697 } 698 switch s := atomic.Load(&t.status); s { 699 case timerDeleted: 700 if atomic.Cas(&t.status, s, timerRemoving) { 701 dodeltimer(pp, i) 702 if !atomic.Cas(&t.status, timerRemoving, timerRemoved) { 703 badTimer() 704 } 705 atomic.Xadd(&pp.deletedTimers, -1) 706 // Look at this heap position again. 707 i-- 708 } 709 case timerModifiedEarlier, timerModifiedLater: 710 if atomic.Cas(&t.status, s, timerMoving) { 711 // Now we can change the when field. 712 t.when = t.nextwhen 713 // Take t off the heap, and hold onto it. 714 // We don't add it back yet because the 715 // heap manipulation could cause our 716 // loop to skip some other timer. 717 dodeltimer(pp, i) 718 moved = append(moved, t) 719 if s == timerModifiedEarlier { 720 if n := atomic.Xadd(&pp.adjustTimers, -1); int32(n) <= 0 { 721 break loop 722 } 723 } 724 // Look at this heap position again. 725 i-- 726 } 727 case timerNoStatus, timerRunning, timerRemoving, timerRemoved, timerMoving: 728 badTimer() 729 case timerWaiting: 730 // OK, nothing to do. 731 case timerModifying: 732 // Check again after modification is complete. 733 osyield() 734 i-- 735 default: 736 badTimer() 737 } 738 } 739 740 if len(moved) > 0 { 741 addAdjustedTimers(pp, moved) 742 } 743 744 if verifyTimers { 745 verifyTimerHeap(pp) 746 } 747 } 748 749 // addAdjustedTimers adds any timers we adjusted in adjusttimers 750 // back to the timer heap. 751 func addAdjustedTimers(pp *p, moved []*timer) { 752 for _, t := range moved { 753 doaddtimer(pp, t) 754 if !atomic.Cas(&t.status, timerMoving, timerWaiting) { 755 badTimer() 756 } 757 } 758 } 759 760 // nobarrierWakeTime looks at P's timers and returns the time when we 761 // should wake up the netpoller. It returns 0 if there are no timers. 762 // This function is invoked when dropping a P, and must run without 763 // any write barriers. 764 //go:nowritebarrierrec 765 func nobarrierWakeTime(pp *p) int64 { 766 next := int64(atomic.Load64(&pp.timer0When)) 767 nextAdj := int64(atomic.Load64(&pp.timerModifiedEarliest)) 768 if next == 0 || (nextAdj != 0 && nextAdj < next) { 769 next = nextAdj 770 } 771 return next 772 } 773 774 // runtimer examines the first timer in timers. If it is ready based on now, 775 // it runs the timer and removes or updates it. 776 // Returns 0 if it ran a timer, -1 if there are no more timers, or the time 777 // when the first timer should run. 778 // The caller must have locked the timers for pp. 779 // If a timer is run, this will temporarily unlock the timers. 780 //go:systemstack 781 func runtimer(pp *p, now int64) int64 { 782 for { 783 t := pp.timers[0] 784 if t.pp.ptr() != pp { 785 throw("runtimer: bad p") 786 } 787 switch s := atomic.Load(&t.status); s { 788 case timerWaiting: 789 if t.when > now { 790 // Not ready to run. 791 return t.when 792 } 793 794 if !atomic.Cas(&t.status, s, timerRunning) { 795 continue 796 } 797 // Note that runOneTimer may temporarily unlock 798 // pp.timersLock. 799 runOneTimer(pp, t, now) 800 return 0 801 802 case timerDeleted: 803 if !atomic.Cas(&t.status, s, timerRemoving) { 804 continue 805 } 806 dodeltimer0(pp) 807 if !atomic.Cas(&t.status, timerRemoving, timerRemoved) { 808 badTimer() 809 } 810 atomic.Xadd(&pp.deletedTimers, -1) 811 if len(pp.timers) == 0 { 812 return -1 813 } 814 815 case timerModifiedEarlier, timerModifiedLater: 816 if !atomic.Cas(&t.status, s, timerMoving) { 817 continue 818 } 819 t.when = t.nextwhen 820 dodeltimer0(pp) 821 doaddtimer(pp, t) 822 if s == timerModifiedEarlier { 823 atomic.Xadd(&pp.adjustTimers, -1) 824 } 825 if !atomic.Cas(&t.status, timerMoving, timerWaiting) { 826 badTimer() 827 } 828 829 case timerModifying: 830 // Wait for modification to complete. 831 osyield() 832 833 case timerNoStatus, timerRemoved: 834 // Should not see a new or inactive timer on the heap. 835 badTimer() 836 case timerRunning, timerRemoving, timerMoving: 837 // These should only be set when timers are locked, 838 // and we didn't do it. 839 badTimer() 840 default: 841 badTimer() 842 } 843 } 844 } 845 846 // runOneTimer runs a single timer. 847 // The caller must have locked the timers for pp. 848 // This will temporarily unlock the timers while running the timer function. 849 //go:systemstack 850 func runOneTimer(pp *p, t *timer, now int64) { 851 if raceenabled { 852 ppcur := getg().m.p.ptr() 853 if ppcur.timerRaceCtx == 0 { 854 ppcur.timerRaceCtx = racegostart(funcPC(runtimer) + sys.PCQuantum) 855 } 856 raceacquirectx(ppcur.timerRaceCtx, unsafe.Pointer(t)) 857 } 858 859 f := t.f 860 arg := t.arg 861 seq := t.seq 862 863 if t.period > 0 { 864 // Leave in heap but adjust next time to fire. 865 delta := t.when - now 866 t.when += t.period * (1 + -delta/t.period) 867 if t.when < 0 { // check for overflow. 868 t.when = maxWhen 869 } 870 siftdownTimer(pp.timers, 0) 871 if !atomic.Cas(&t.status, timerRunning, timerWaiting) { 872 badTimer() 873 } 874 updateTimer0When(pp) 875 } else { 876 // Remove from heap. 877 dodeltimer0(pp) 878 if !atomic.Cas(&t.status, timerRunning, timerNoStatus) { 879 badTimer() 880 } 881 } 882 883 if raceenabled { 884 // Temporarily use the current P's racectx for g0. 885 gp := getg() 886 if gp.racectx != 0 { 887 throw("runOneTimer: unexpected racectx") 888 } 889 gp.racectx = gp.m.p.ptr().timerRaceCtx 890 } 891 892 unlock(&pp.timersLock) 893 894 f(arg, seq) 895 896 lock(&pp.timersLock) 897 898 if raceenabled { 899 gp := getg() 900 gp.racectx = 0 901 } 902 } 903 904 // clearDeletedTimers removes all deleted timers from the P's timer heap. 905 // This is used to avoid clogging up the heap if the program 906 // starts a lot of long-running timers and then stops them. 907 // For example, this can happen via context.WithTimeout. 908 // 909 // This is the only function that walks through the entire timer heap, 910 // other than moveTimers which only runs when the world is stopped. 911 // 912 // The caller must have locked the timers for pp. 913 func clearDeletedTimers(pp *p) { 914 // We are going to clear all timerModifiedEarlier timers. 915 // Do this now in case new ones show up while we are looping. 916 atomic.Store64(&pp.timerModifiedEarliest, 0) 917 918 cdel := int32(0) 919 cearlier := int32(0) 920 to := 0 921 changedHeap := false 922 timers := pp.timers 923 nextTimer: 924 for _, t := range timers { 925 for { 926 switch s := atomic.Load(&t.status); s { 927 case timerWaiting: 928 if changedHeap { 929 timers[to] = t 930 siftupTimer(timers, to) 931 } 932 to++ 933 continue nextTimer 934 case timerModifiedEarlier, timerModifiedLater: 935 if atomic.Cas(&t.status, s, timerMoving) { 936 t.when = t.nextwhen 937 timers[to] = t 938 siftupTimer(timers, to) 939 to++ 940 changedHeap = true 941 if !atomic.Cas(&t.status, timerMoving, timerWaiting) { 942 badTimer() 943 } 944 if s == timerModifiedEarlier { 945 cearlier++ 946 } 947 continue nextTimer 948 } 949 case timerDeleted: 950 if atomic.Cas(&t.status, s, timerRemoving) { 951 t.pp = 0 952 cdel++ 953 if !atomic.Cas(&t.status, timerRemoving, timerRemoved) { 954 badTimer() 955 } 956 changedHeap = true 957 continue nextTimer 958 } 959 case timerModifying: 960 // Loop until modification complete. 961 osyield() 962 case timerNoStatus, timerRemoved: 963 // We should not see these status values in a timer heap. 964 badTimer() 965 case timerRunning, timerRemoving, timerMoving: 966 // Some other P thinks it owns this timer, 967 // which should not happen. 968 badTimer() 969 default: 970 badTimer() 971 } 972 } 973 } 974 975 // Set remaining slots in timers slice to nil, 976 // so that the timer values can be garbage collected. 977 for i := to; i < len(timers); i++ { 978 timers[i] = nil 979 } 980 981 atomic.Xadd(&pp.deletedTimers, -cdel) 982 atomic.Xadd(&pp.numTimers, -cdel) 983 atomic.Xadd(&pp.adjustTimers, -cearlier) 984 985 timers = timers[:to] 986 pp.timers = timers 987 updateTimer0When(pp) 988 989 if verifyTimers { 990 verifyTimerHeap(pp) 991 } 992 } 993 994 // verifyTimerHeap verifies that the timer heap is in a valid state. 995 // This is only for debugging, and is only called if verifyTimers is true. 996 // The caller must have locked the timers. 997 func verifyTimerHeap(pp *p) { 998 for i, t := range pp.timers { 999 if i == 0 { 1000 // First timer has no parent. 1001 continue 1002 } 1003 1004 // The heap is 4-ary. See siftupTimer and siftdownTimer. 1005 p := (i - 1) / 4 1006 if t.when < pp.timers[p].when { 1007 print("bad timer heap at ", i, ": ", p, ": ", pp.timers[p].when, ", ", i, ": ", t.when, "\n") 1008 throw("bad timer heap") 1009 } 1010 } 1011 if numTimers := int(atomic.Load(&pp.numTimers)); len(pp.timers) != numTimers { 1012 println("timer heap len", len(pp.timers), "!= numTimers", numTimers) 1013 throw("bad timer heap len") 1014 } 1015 } 1016 1017 // updateTimer0When sets the P's timer0When field. 1018 // The caller must have locked the timers for pp. 1019 func updateTimer0When(pp *p) { 1020 if len(pp.timers) == 0 { 1021 atomic.Store64(&pp.timer0When, 0) 1022 } else { 1023 atomic.Store64(&pp.timer0When, uint64(pp.timers[0].when)) 1024 } 1025 } 1026 1027 // updateTimerModifiedEarliest updates the recorded nextwhen field of the 1028 // earlier timerModifiedEarier value. 1029 // The timers for pp will not be locked. 1030 func updateTimerModifiedEarliest(pp *p, nextwhen int64) { 1031 for { 1032 old := atomic.Load64(&pp.timerModifiedEarliest) 1033 if old != 0 && int64(old) < nextwhen { 1034 return 1035 } 1036 if atomic.Cas64(&pp.timerModifiedEarliest, old, uint64(nextwhen)) { 1037 return 1038 } 1039 } 1040 } 1041 1042 // timeSleepUntil returns the time when the next timer should fire, 1043 // and the P that holds the timer heap that that timer is on. 1044 // This is only called by sysmon and checkdead. 1045 func timeSleepUntil() (int64, *p) { 1046 next := int64(maxWhen) 1047 var pret *p 1048 1049 // Prevent allp slice changes. This is like retake. 1050 lock(&allpLock) 1051 for _, pp := range allp { 1052 if pp == nil { 1053 // This can happen if procresize has grown 1054 // allp but not yet created new Ps. 1055 continue 1056 } 1057 1058 w := int64(atomic.Load64(&pp.timer0When)) 1059 if w != 0 && w < next { 1060 next = w 1061 pret = pp 1062 } 1063 1064 w = int64(atomic.Load64(&pp.timerModifiedEarliest)) 1065 if w != 0 && w < next { 1066 next = w 1067 pret = pp 1068 } 1069 } 1070 unlock(&allpLock) 1071 1072 return next, pret 1073 } 1074 1075 // Heap maintenance algorithms. 1076 // These algorithms check for slice index errors manually. 1077 // Slice index error can happen if the program is using racy 1078 // access to timers. We don't want to panic here, because 1079 // it will cause the program to crash with a mysterious 1080 // "panic holding locks" message. Instead, we panic while not 1081 // holding a lock. 1082 1083 func siftupTimer(t []*timer, i int) { 1084 if i >= len(t) { 1085 badTimer() 1086 } 1087 when := t[i].when 1088 if when <= 0 { 1089 badTimer() 1090 } 1091 tmp := t[i] 1092 for i > 0 { 1093 p := (i - 1) / 4 // parent 1094 if when >= t[p].when { 1095 break 1096 } 1097 t[i] = t[p] 1098 i = p 1099 } 1100 if tmp != t[i] { 1101 t[i] = tmp 1102 } 1103 } 1104 1105 func siftdownTimer(t []*timer, i int) { 1106 n := len(t) 1107 if i >= n { 1108 badTimer() 1109 } 1110 when := t[i].when 1111 if when <= 0 { 1112 badTimer() 1113 } 1114 tmp := t[i] 1115 for { 1116 c := i*4 + 1 // left child 1117 c3 := c + 2 // mid child 1118 if c >= n { 1119 break 1120 } 1121 w := t[c].when 1122 if c+1 < n && t[c+1].when < w { 1123 w = t[c+1].when 1124 c++ 1125 } 1126 if c3 < n { 1127 w3 := t[c3].when 1128 if c3+1 < n && t[c3+1].when < w3 { 1129 w3 = t[c3+1].when 1130 c3++ 1131 } 1132 if w3 < w { 1133 w = w3 1134 c = c3 1135 } 1136 } 1137 if w >= when { 1138 break 1139 } 1140 t[i] = t[c] 1141 i = c 1142 } 1143 if tmp != t[i] { 1144 t[i] = tmp 1145 } 1146 } 1147 1148 // badTimer is called if the timer data structures have been corrupted, 1149 // presumably due to racy use by the program. We panic here rather than 1150 // panicing due to invalid slice access while holding locks. 1151 // See issue #25686. 1152 func badTimer() { 1153 throw("timer data corruption") 1154 }