]> Cypherpunks.ru repositories - gostls13.git/blob - src/runtime/time.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / src / runtime / time.go
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, traceBlockSleep, 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 && 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 // panicking due to invalid slice access while holding locks.
1141 // See issue #25686.
1142 func badTimer() {
1143         throw("timer data corruption")
1144 }