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