github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/runtime/time.go (about)

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