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