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