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.
5 // Time-related runtime and pieces of package time.
11 "runtime/internal/atomic"
12 "runtime/internal/sys"
16 // Package time knows the layout of this structure.
17 // If this struct changes, adjust ../time/sleep.go:/runtimeTimer.
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.
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.
28 // when must be positive on an active timer.
35 // What to set the when field to in timerModifiedXX status.
38 // The status field holds one of the values below.
42 // Code outside this file has to be careful in using a timer value.
44 // The pp, status, and nextwhen fields may only be used by code in this file.
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.
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.
60 // An active timer may be passed to modtimer. No fields may be touched.
61 // It remains an active timer.
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.
67 // Timer operations are addtimer, deltimer, modtimer, resettimer,
68 // cleantimers, adjusttimers, and runtimer.
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.
73 // Active timers live in heaps attached to P, in the timers field.
74 // Inactive timers live there too temporarily, until they are removed.
77 // timerNoStatus -> timerWaiting
78 // anything else -> panic: invalid value
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
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
119 // Values for the timer status field.
121 // Timer has no status set yet.
124 // Waiting for timer to fire.
125 // The timer is in some P's heap.
128 // Running the timer function.
129 // A timer will only have this status briefly.
132 // The timer is deleted and should be removed.
133 // It should not be run, but it is still in some P's heap.
136 // The timer is being removed.
137 // The timer will only have this status briefly.
140 // The timer has been stopped.
141 // It is not in any P's heap.
144 // The timer is being modified.
145 // The timer will only have this status briefly.
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.
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.
158 // The timer has been modified and is being moved.
159 // The timer will only have this status briefly.
163 // maxWhen is the maximum value for timer's when field.
164 const maxWhen = 1<<63 - 1
166 // verifyTimers can be set to true to add debugging checks that the
167 // timer heaps are valid.
168 const verifyTimers = false
170 // Package time APIs.
171 // Godoc uses the comments in package time, not these.
173 // time.now is implemented in assembly.
175 // timeSleep puts the current goroutine to sleep for at least ns nanoseconds.
177 //go:linkname timeSleep time.Sleep
178 func timeSleep(ns int64) {
191 t.nextwhen = nanotime() + ns
192 if t.nextwhen < 0 { // check for overflow.
195 gopark(resetForSleep, unsafe.Pointer(t), waitReasonSleep, traceBlockSleep, 1)
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 {
204 resettimer(t, t.nextwhen)
208 // startTimer adds t to the timer heap.
210 //go:linkname startTimer time.startTimer
211 func startTimer(t *timer) {
213 racerelease(unsafe.Pointer(t))
218 // stopTimer stops a timer.
219 // It reports whether t was stopped before being run.
221 //go:linkname stopTimer time.stopTimer
222 func stopTimer(t *timer) bool {
226 // resetTimer resets an inactive timer, adding it to the heap.
228 // Reports whether the timer was modified before it was run.
230 //go:linkname resetTimer time.resetTimer
231 func resetTimer(t *timer, when int64) bool {
233 racerelease(unsafe.Pointer(t))
235 return resettimer(t, when)
238 // modTimer modifies an existing timer.
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)
247 // Ready the goroutine arg.
248 func goroutineReady(arg any, seq uintptr) {
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.
262 throw("timer when must be positive")
265 throw("timer period must be non-negative")
267 if t.status.Load() != timerNoStatus {
268 throw("addtimer called with initialized timer")
270 t.status.Store(timerWaiting)
274 // Disable preemption while using pp to avoid changing another P's heap.
277 pp := getg().m.p.ptr()
281 unlock(&pp.timersLock)
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
293 if netpollInited.Load() == 0 {
298 throw("doaddtimer: P already set in timer")
302 pp.timers = append(pp.timers, t)
303 siftupTimer(pp.timers, i)
304 if t == pp.timers[0] {
305 pp.timer0When.Store(t.when)
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 {
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.
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.
326 if !t.status.CompareAndSwap(timerModifying, timerDeleted) {
330 tpp.deletedTimers.Add(1)
331 // Timer was not yet run.
336 case timerModifiedEarlier:
337 // Prevent preemption while the timer is in timerModifying.
338 // This could lead to a self-deadlock. See #38070.
340 if t.status.CompareAndSwap(s, timerModifying) {
341 // Must fetch t.pp before setting status
344 if !t.status.CompareAndSwap(timerModifying, timerDeleted) {
348 tpp.deletedTimers.Add(1)
349 // Timer was not yet run.
354 case timerDeleted, timerRemoving, timerRemoved:
355 // Timer was already run.
357 case timerRunning, timerMoving:
358 // The timer is being run or moved, by a different P.
359 // Wait for it to complete.
362 // Removing timer that was never added or
363 // has already been run. Also see issue 21874.
366 // Simultaneous calls to deltimer and modtimer.
367 // Wait for the other call to complete.
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")
385 last := len(pp.timers) - 1
387 pp.timers[i] = pp.timers[last]
389 pp.timers[last] = nil
390 pp.timers = pp.timers[: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)
401 n := pp.numTimers.Add(-1)
403 // If there are no timers, then clearly none are modified.
404 pp.timerModifiedEarliest.Store(0)
406 return smallestChanged
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")
419 last := len(pp.timers) - 1
421 pp.timers[0] = pp.timers[last]
423 pp.timers[last] = nil
424 pp.timers = pp.timers[:last]
426 siftdownTimer(pp.timers, 0)
429 n := pp.numTimers.Add(-1)
431 // If there are no timers, then clearly none are modified.
432 pp.timerModifiedEarliest.Store(0)
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 {
441 throw("timer when must be positive")
444 throw("timer period must be non-negative")
447 status := uint32(timerNoStatus)
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.
458 if t.status.CompareAndSwap(status, timerModifying) {
459 pending = true // timer not yet run
463 case timerNoStatus, timerRemoved:
464 // Prevent preemption while the timer is in timerModifying.
465 // This could lead to a self-deadlock. See #38070.
468 // Timer was already run and t is no longer in a heap.
469 // Act like addtimer.
470 if t.status.CompareAndSwap(status, timerModifying) {
472 pending = false // timer already run or stopped
477 // Prevent preemption while the timer is in timerModifying.
478 // This could lead to a self-deadlock. See #38070.
480 if t.status.CompareAndSwap(status, timerModifying) {
481 t.pp.ptr().deletedTimers.Add(-1)
482 pending = false // timer already stopped
486 case timerRunning, timerRemoving, timerMoving:
487 // The timer is being run or moved, by a different P.
488 // Wait for it to complete.
491 // Multiple simultaneous calls to modtimer.
492 // Wait for the other call to complete.
506 pp := getg().m.p.ptr()
509 unlock(&pp.timersLock)
510 if !t.status.CompareAndSwap(timerModifying, timerWaiting) {
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.
523 newStatus := uint32(timerModifiedLater)
525 newStatus = timerModifiedEarlier
530 if newStatus == timerModifiedEarlier {
531 updateTimerModifiedEarliest(tpp, when)
534 // Set the new status of the timer.
535 if !t.status.CompareAndSwap(timerModifying, newStatus) {
540 // If the new status is earlier, wake up the poller.
541 if newStatus == timerModifiedEarlier {
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)
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) {
565 if len(pp.timers) == 0 {
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.
578 if t.pp.ptr() != pp {
579 throw("cleantimers: bad p")
581 switch s := t.status.Load(); s {
583 if !t.status.CompareAndSwap(s, timerRemoving) {
587 if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
590 pp.deletedTimers.Add(-1)
591 case timerModifiedEarlier, timerModifiedLater:
592 if !t.status.CompareAndSwap(s, timerMoving) {
595 // Now we can change the when field.
597 // Move t to the right position.
600 if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
604 // Head of timers does not need adjustment.
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 {
618 switch s := t.status.Load(); s {
620 if !t.status.CompareAndSwap(s, timerMoving) {
625 if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
629 case timerModifiedEarlier, timerModifiedLater:
630 if !t.status.CompareAndSwap(s, timerMoving) {
636 if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
641 if !t.status.CompareAndSwap(s, timerRemoved) {
645 // We no longer need this timer in the heap.
648 // Loop until the modification is complete.
650 case timerNoStatus, timerRemoved:
651 // We should not see these status values in a timers heap.
653 case timerRunning, timerRemoving, timerMoving:
654 // Some other P thinks it owns this timer,
655 // which should not happen.
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 {
683 // We are going to clear all timerModifiedEarlier timers.
684 pp.timerModifiedEarliest.Store(0)
687 for i := 0; i < len(pp.timers); i++ {
689 if t.pp.ptr() != pp {
690 throw("adjusttimers: bad p")
692 switch s := t.status.Load(); s {
694 if t.status.CompareAndSwap(s, timerRemoving) {
695 changed := dodeltimer(pp, i)
696 if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
699 pp.deletedTimers.Add(-1)
700 // Go back to the earliest changed heap entry.
701 // "- 1" because the loop will add 1.
704 case timerModifiedEarlier, timerModifiedLater:
705 if t.status.CompareAndSwap(s, timerMoving) {
706 // Now we can change the when field.
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.
718 case timerNoStatus, timerRunning, timerRemoving, timerRemoved, timerMoving:
721 // OK, nothing to do.
723 // Check again after modification is complete.
732 addAdjustedTimers(pp, moved)
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 {
745 if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
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.
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) {
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.
774 func runtimer(pp *p, now int64) int64 {
777 if t.pp.ptr() != pp {
778 throw("runtimer: bad p")
780 switch s := t.status.Load(); s {
787 if !t.status.CompareAndSwap(s, timerRunning) {
790 // Note that runOneTimer may temporarily unlock
792 runOneTimer(pp, t, now)
796 if !t.status.CompareAndSwap(s, timerRemoving) {
800 if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
803 pp.deletedTimers.Add(-1)
804 if len(pp.timers) == 0 {
808 case timerModifiedEarlier, timerModifiedLater:
809 if !t.status.CompareAndSwap(s, timerMoving) {
815 if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
820 // Wait for modification to complete.
823 case timerNoStatus, timerRemoved:
824 // Should not see a new or inactive timer on the heap.
826 case timerRunning, timerRemoving, timerMoving:
827 // These should only be set when timers are locked,
828 // and we didn't do it.
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.
841 func runOneTimer(pp *p, t *timer, now int64) {
843 ppcur := getg().m.p.ptr()
844 if ppcur.timerRaceCtx == 0 {
845 ppcur.timerRaceCtx = racegostart(abi.FuncPCABIInternal(runtimer) + sys.PCQuantum)
847 raceacquirectx(ppcur.timerRaceCtx, unsafe.Pointer(t))
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.
861 siftdownTimer(pp.timers, 0)
862 if !t.status.CompareAndSwap(timerRunning, timerWaiting) {
869 if !t.status.CompareAndSwap(timerRunning, timerNoStatus) {
875 // Temporarily use the current P's racectx for g0.
878 throw("runOneTimer: unexpected racectx")
880 gp.racectx = gp.m.p.ptr().timerRaceCtx
883 unlock(&pp.timersLock)
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.
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.
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)
914 for _, t := range timers {
916 switch s := t.status.Load(); s {
920 siftupTimer(timers, to)
924 case timerModifiedEarlier, timerModifiedLater:
925 if t.status.CompareAndSwap(s, timerMoving) {
928 siftupTimer(timers, to)
931 if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
937 if t.status.CompareAndSwap(s, timerRemoving) {
940 if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
947 // Loop until modification complete.
949 case timerNoStatus, timerRemoved:
950 // We should not see these status values in a timer heap.
952 case timerRunning, timerRemoving, timerMoving:
953 // Some other P thinks it owns this timer,
954 // which should not happen.
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++ {
968 pp.deletedTimers.Add(-cdel)
969 pp.numTimers.Add(-cdel)
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 {
986 // First timer has no parent.
990 // The heap is 4-ary. See siftupTimer and siftdownTimer.
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")
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")
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)
1009 pp.timer0When.Store(pp.timers[0].when)
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) {
1018 old := pp.timerModifiedEarliest.Load()
1019 if old != 0 && old < nextwhen {
1023 if pp.timerModifiedEarliest.CompareAndSwap(old, nextwhen) {
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)
1035 // Prevent allp slice changes. This is like retake.
1037 for _, pp := range allp {
1039 // This can happen if procresize has grown
1040 // allp but not yet created new Ps.
1044 w := pp.timer0When.Load()
1045 if w != 0 && w < next {
1049 w = pp.timerModifiedEarliest.Load()
1050 if w != 0 && w < next {
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
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 {
1080 p := (i - 1) / 4 // parent
1081 if when >= t[p].when {
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) {
1106 c := i*4 + 1 // left child
1107 c3 := c + 2 // mid child
1112 if c+1 < n && t[c+1].when < w {
1118 if c3+1 < n && t[c3+1].when < w3 {
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 // panicking due to invalid slice access while holding locks.
1141 // See issue #25686.
1143 throw("timer data corruption")