github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/runtime/time.go (about)

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