// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Time-related runtime and pieces of package time.

package runtime

import (
	
	
	
	
)

// Package time knows the layout of this structure.
// If this struct changes, adjust ../time/sleep.go:/runtimeTimer.
type timer struct {
	// If this timer is on a heap, which P's heap it is on.
	// puintptr rather than *p to match uintptr in the versions
	// of this struct defined in other packages.
	pp puintptr

	// Timer wakes up at when, and then at when+period, ... (period > 0 only)
	// each time calling f(arg, now) in the timer goroutine, so f must be
	// a well-behaved function and not block.
	//
	// when must be positive on an active timer.
	when   int64
	period int64
	f      func(any, uintptr)
	arg    any
	seq    uintptr

	// What to set the when field to in timerModifiedXX status.
	nextwhen int64

	// The status field holds one of the values below.
	status atomic.Uint32
}

// Code outside this file has to be careful in using a timer value.
//
// The pp, status, and nextwhen fields may only be used by code in this file.
//
// Code that creates a new timer value can set the when, period, f,
// arg, and seq fields.
// A new timer value may be passed to addtimer (called by time.startTimer).
// After doing that no fields may be touched.
//
// An active timer (one that has been passed to addtimer) may be
// passed to deltimer (time.stopTimer), after which it is no longer an
// active timer. It is an inactive timer.
// In an inactive timer the period, f, arg, and seq fields may be modified,
// but not the when field.
// It's OK to just drop an inactive timer and let the GC collect it.
// It's not OK to pass an inactive timer to addtimer.
// Only newly allocated timer values may be passed to addtimer.
//
// An active timer may be passed to modtimer. No fields may be touched.
// It remains an active timer.
//
// An inactive timer may be passed to resettimer to turn into an
// active timer with an updated when field.
// It's OK to pass a newly allocated timer value to resettimer.
//
// Timer operations are addtimer, deltimer, modtimer, resettimer,
// cleantimers, adjusttimers, and runtimer.
//
// We don't permit calling addtimer/deltimer/modtimer/resettimer simultaneously,
// but adjusttimers and runtimer can be called at the same time as any of those.
//
// Active timers live in heaps attached to P, in the timers field.
// Inactive timers live there too temporarily, until they are removed.
//
// addtimer:
//   timerNoStatus   -> timerWaiting
//   anything else   -> panic: invalid value
// deltimer:
//   timerWaiting         -> timerModifying -> timerDeleted
//   timerModifiedEarlier -> timerModifying -> timerDeleted
//   timerModifiedLater   -> timerModifying -> timerDeleted
//   timerNoStatus        -> do nothing
//   timerDeleted         -> do nothing
//   timerRemoving        -> do nothing
//   timerRemoved         -> do nothing
//   timerRunning         -> wait until status changes
//   timerMoving          -> wait until status changes
//   timerModifying       -> wait until status changes
// modtimer:
//   timerWaiting    -> timerModifying -> timerModifiedXX
//   timerModifiedXX -> timerModifying -> timerModifiedYY
//   timerNoStatus   -> timerModifying -> timerWaiting
//   timerRemoved    -> timerModifying -> timerWaiting
//   timerDeleted    -> timerModifying -> timerModifiedXX
//   timerRunning    -> wait until status changes
//   timerMoving     -> wait until status changes
//   timerRemoving   -> wait until status changes
//   timerModifying  -> wait until status changes
// cleantimers (looks in P's timer heap):
//   timerDeleted    -> timerRemoving -> timerRemoved
//   timerModifiedXX -> timerMoving -> timerWaiting
// adjusttimers (looks in P's timer heap):
//   timerDeleted    -> timerRemoving -> timerRemoved
//   timerModifiedXX -> timerMoving -> timerWaiting
// runtimer (looks in P's timer heap):
//   timerNoStatus   -> panic: uninitialized timer
//   timerWaiting    -> timerWaiting or
//   timerWaiting    -> timerRunning -> timerNoStatus or
//   timerWaiting    -> timerRunning -> timerWaiting
//   timerModifying  -> wait until status changes
//   timerModifiedXX -> timerMoving -> timerWaiting
//   timerDeleted    -> timerRemoving -> timerRemoved
//   timerRunning    -> panic: concurrent runtimer calls
//   timerRemoved    -> panic: inconsistent timer heap
//   timerRemoving   -> panic: inconsistent timer heap
//   timerMoving     -> panic: inconsistent timer heap

// Values for the timer status field.
const (
	// Timer has no status set yet.
	timerNoStatus = iota

	// Waiting for timer to fire.
	// The timer is in some P's heap.
	timerWaiting

	// Running the timer function.
	// A timer will only have this status briefly.
	timerRunning

	// The timer is deleted and should be removed.
	// It should not be run, but it is still in some P's heap.
	timerDeleted

	// The timer is being removed.
	// The timer will only have this status briefly.
	timerRemoving

	// The timer has been stopped.
	// It is not in any P's heap.
	timerRemoved

	// The timer is being modified.
	// The timer will only have this status briefly.
	timerModifying

	// The timer has been modified to an earlier time.
	// The new when value is in the nextwhen field.
	// The timer is in some P's heap, possibly in the wrong place.
	timerModifiedEarlier

	// The timer has been modified to the same or a later time.
	// The new when value is in the nextwhen field.
	// The timer is in some P's heap, possibly in the wrong place.
	timerModifiedLater

	// The timer has been modified and is being moved.
	// The timer will only have this status briefly.
	timerMoving
)

// maxWhen is the maximum value for timer's when field.
const maxWhen = 1<<63 - 1

// verifyTimers can be set to true to add debugging checks that the
// timer heaps are valid.
const verifyTimers = false

// Package time APIs.
// Godoc uses the comments in package time, not these.

// time.now is implemented in assembly.

// timeSleep puts the current goroutine to sleep for at least ns nanoseconds.
//
//go:linkname timeSleep time.Sleep
func timeSleep( int64) {
	if  <= 0 {
		return
	}

	 := getg()
	 := .timer
	if  == nil {
		 = new(timer)
		.timer = 
	}
	.f = goroutineReady
	.arg = 
	.nextwhen = nanotime() + 
	if .nextwhen < 0 { // check for overflow.
		.nextwhen = maxWhen
	}
	gopark(resetForSleep, unsafe.Pointer(), waitReasonSleep, traceBlockSleep, 1)
}

// resetForSleep is called after the goroutine is parked for timeSleep.
// We can't call resettimer in timeSleep itself because if this is a short
// sleep and there are many goroutines then the P can wind up running the
// timer function, goroutineReady, before the goroutine has been parked.
func resetForSleep( *g,  unsafe.Pointer) bool {
	 := (*timer)()
	resettimer(, .nextwhen)
	return true
}

// startTimer adds t to the timer heap.
//
//go:linkname startTimer time.startTimer
func startTimer( *timer) {
	if raceenabled {
		racerelease(unsafe.Pointer())
	}
	addtimer()
}

// stopTimer stops a timer.
// It reports whether t was stopped before being run.
//
//go:linkname stopTimer time.stopTimer
func stopTimer( *timer) bool {
	return deltimer()
}

// resetTimer resets an inactive timer, adding it to the heap.
//
// Reports whether the timer was modified before it was run.
//
//go:linkname resetTimer time.resetTimer
func resetTimer( *timer,  int64) bool {
	if raceenabled {
		racerelease(unsafe.Pointer())
	}
	return resettimer(, )
}

// modTimer modifies an existing timer.
//
//go:linkname modTimer time.modTimer
func modTimer( *timer, ,  int64,  func(any, uintptr),  any,  uintptr) {
	modtimer(, , , , , )
}

// Go runtime.

// Ready the goroutine arg.
func goroutineReady( any,  uintptr) {
	goready(.(*g), 0)
}

// Note: this changes some unsynchronized operations to synchronized operations
// addtimer adds a timer to the current P.
// This should only be called with a newly created timer.
// That avoids the risk of changing the when field of a timer in some P's heap,
// which could cause the heap to become unsorted.
func addtimer( *timer) {
	// when must be positive. A negative value will cause runtimer to
	// overflow during its delta calculation and never expire other runtime
	// timers. Zero will cause checkTimers to fail to notice the timer.
	if .when <= 0 {
		throw("timer when must be positive")
	}
	if .period < 0 {
		throw("timer period must be non-negative")
	}
	if .status.Load() != timerNoStatus {
		throw("addtimer called with initialized timer")
	}
	.status.Store(timerWaiting)

	 := .when

	// Disable preemption while using pp to avoid changing another P's heap.
	 := acquirem()

	 := getg().m.p.ptr()
	lock(&.timersLock)
	cleantimers()
	doaddtimer(, )
	unlock(&.timersLock)

	wakeNetPoller()

	releasem()
}

// doaddtimer adds t to the current P's heap.
// The caller must have locked the timers for pp.
func doaddtimer( *p,  *timer) {
	// Timers rely on the network poller, so make sure the poller
	// has started.
	if netpollInited.Load() == 0 {
		netpollGenericInit()
	}

	if .pp != 0 {
		throw("doaddtimer: P already set in timer")
	}
	.pp.set()
	 := len(.timers)
	.timers = append(.timers, )
	siftupTimer(.timers, )
	if  == .timers[0] {
		.timer0When.Store(.when)
	}
	.numTimers.Add(1)
}

// deltimer deletes the timer t. It may be on some other P, so we can't
// actually remove it from the timers heap. We can only mark it as deleted.
// It will be removed in due course by the P whose heap it is on.
// Reports whether the timer was removed before it was run.
func deltimer( *timer) bool {
	for {
		switch  := .status.Load();  {
		case timerWaiting, timerModifiedLater:
			// Prevent preemption while the timer is in timerModifying.
			// This could lead to a self-deadlock. See #38070.
			 := acquirem()
			if .status.CompareAndSwap(, timerModifying) {
				// Must fetch t.pp before changing status,
				// as cleantimers in another goroutine
				// can clear t.pp of a timerDeleted timer.
				 := .pp.ptr()
				if !.status.CompareAndSwap(timerModifying, timerDeleted) {
					badTimer()
				}
				releasem()
				.deletedTimers.Add(1)
				// Timer was not yet run.
				return true
			} else {
				releasem()
			}
		case timerModifiedEarlier:
			// Prevent preemption while the timer is in timerModifying.
			// This could lead to a self-deadlock. See #38070.
			 := acquirem()
			if .status.CompareAndSwap(, timerModifying) {
				// Must fetch t.pp before setting status
				// to timerDeleted.
				 := .pp.ptr()
				if !.status.CompareAndSwap(timerModifying, timerDeleted) {
					badTimer()
				}
				releasem()
				.deletedTimers.Add(1)
				// Timer was not yet run.
				return true
			} else {
				releasem()
			}
		case timerDeleted, timerRemoving, timerRemoved:
			// Timer was already run.
			return false
		case timerRunning, timerMoving:
			// The timer is being run or moved, by a different P.
			// Wait for it to complete.
			osyield()
		case timerNoStatus:
			// Removing timer that was never added or
			// has already been run. Also see issue 21874.
			return false
		case timerModifying:
			// Simultaneous calls to deltimer and modtimer.
			// Wait for the other call to complete.
			osyield()
		default:
			badTimer()
		}
	}
}

// dodeltimer removes timer i from the current P's heap.
// We are locked on the P when this is called.
// It returns the smallest changed index in pp.timers.
// The caller must have locked the timers for pp.
func dodeltimer( *p,  int) int {
	if  := .timers[]; .pp.ptr() !=  {
		throw("dodeltimer: wrong P")
	} else {
		.pp = 0
	}
	 := len(.timers) - 1
	if  !=  {
		.timers[] = .timers[]
	}
	.timers[] = nil
	.timers = .timers[:]
	 := 
	if  !=  {
		// Moving to i may have moved the last timer to a new parent,
		// so sift up to preserve the heap guarantee.
		 = siftupTimer(.timers, )
		siftdownTimer(.timers, )
	}
	if  == 0 {
		updateTimer0When()
	}
	 := .numTimers.Add(-1)
	if  == 0 {
		// If there are no timers, then clearly none are modified.
		.timerModifiedEarliest.Store(0)
	}
	return 
}

// dodeltimer0 removes timer 0 from the current P's heap.
// We are locked on the P when this is called.
// It reports whether it saw no problems due to races.
// The caller must have locked the timers for pp.
func dodeltimer0( *p) {
	if  := .timers[0]; .pp.ptr() !=  {
		throw("dodeltimer0: wrong P")
	} else {
		.pp = 0
	}
	 := len(.timers) - 1
	if  > 0 {
		.timers[0] = .timers[]
	}
	.timers[] = nil
	.timers = .timers[:]
	if  > 0 {
		siftdownTimer(.timers, 0)
	}
	updateTimer0When()
	 := .numTimers.Add(-1)
	if  == 0 {
		// If there are no timers, then clearly none are modified.
		.timerModifiedEarliest.Store(0)
	}
}

// modtimer modifies an existing timer.
// This is called by the netpoll code or time.Ticker.Reset or time.Timer.Reset.
// Reports whether the timer was modified before it was run.
func modtimer( *timer, ,  int64,  func(any, uintptr),  any,  uintptr) bool {
	if  <= 0 {
		throw("timer when must be positive")
	}
	if  < 0 {
		throw("timer period must be non-negative")
	}

	 := uint32(timerNoStatus)
	 := false
	var  bool
	var  *m
:
	for {
		switch  = .status.Load();  {
		case timerWaiting, timerModifiedEarlier, timerModifiedLater:
			// Prevent preemption while the timer is in timerModifying.
			// This could lead to a self-deadlock. See #38070.
			 = acquirem()
			if .status.CompareAndSwap(, timerModifying) {
				 = true // timer not yet run
				break 
			}
			releasem()
		case timerNoStatus, timerRemoved:
			// Prevent preemption while the timer is in timerModifying.
			// This could lead to a self-deadlock. See #38070.
			 = acquirem()

			// Timer was already run and t is no longer in a heap.
			// Act like addtimer.
			if .status.CompareAndSwap(, timerModifying) {
				 = true
				 = false // timer already run or stopped
				break 
			}
			releasem()
		case timerDeleted:
			// Prevent preemption while the timer is in timerModifying.
			// This could lead to a self-deadlock. See #38070.
			 = acquirem()
			if .status.CompareAndSwap(, timerModifying) {
				.pp.ptr().deletedTimers.Add(-1)
				 = false // timer already stopped
				break 
			}
			releasem()
		case timerRunning, timerRemoving, timerMoving:
			// The timer is being run or moved, by a different P.
			// Wait for it to complete.
			osyield()
		case timerModifying:
			// Multiple simultaneous calls to modtimer.
			// Wait for the other call to complete.
			osyield()
		default:
			badTimer()
		}
	}

	.period = 
	.f = 
	.arg = 
	.seq = 

	if  {
		.when = 
		 := getg().m.p.ptr()
		lock(&.timersLock)
		doaddtimer(, )
		unlock(&.timersLock)
		if !.status.CompareAndSwap(timerModifying, timerWaiting) {
			badTimer()
		}
		releasem()
		wakeNetPoller()
	} else {
		// The timer is in some other P's heap, so we can't change
		// the when field. If we did, the other P's heap would
		// be out of order. So we put the new when value in the
		// nextwhen field, and let the other P set the when field
		// when it is prepared to resort the heap.
		.nextwhen = 

		 := uint32(timerModifiedLater)
		if  < .when {
			 = timerModifiedEarlier
		}

		 := .pp.ptr()

		if  == timerModifiedEarlier {
			updateTimerModifiedEarliest(, )
		}

		// Set the new status of the timer.
		if !.status.CompareAndSwap(timerModifying, ) {
			badTimer()
		}
		releasem()

		// If the new status is earlier, wake up the poller.
		if  == timerModifiedEarlier {
			wakeNetPoller()
		}
	}

	return 
}

// resettimer resets the time when a timer should fire.
// If used for an inactive timer, the timer will become active.
// This should be called instead of addtimer if the timer value has been,
// or may have been, used previously.
// Reports whether the timer was modified before it was run.
func resettimer( *timer,  int64) bool {
	return modtimer(, , .period, .f, .arg, .seq)
}

// cleantimers cleans up the head of the timer queue. This speeds up
// programs that create and delete timers; leaving them in the heap
// slows down addtimer. Reports whether no timer problems were found.
// The caller must have locked the timers for pp.
func cleantimers( *p) {
	 := getg()
	for {
		if len(.timers) == 0 {
			return
		}

		// This loop can theoretically run for a while, and because
		// it is holding timersLock it cannot be preempted.
		// If someone is trying to preempt us, just return.
		// We can clean the timers later.
		if .preemptStop {
			return
		}

		 := .timers[0]
		if .pp.ptr() !=  {
			throw("cleantimers: bad p")
		}
		switch  := .status.Load();  {
		case timerDeleted:
			if !.status.CompareAndSwap(, timerRemoving) {
				continue
			}
			dodeltimer0()
			if !.status.CompareAndSwap(timerRemoving, timerRemoved) {
				badTimer()
			}
			.deletedTimers.Add(-1)
		case timerModifiedEarlier, timerModifiedLater:
			if !.status.CompareAndSwap(, timerMoving) {
				continue
			}
			// Now we can change the when field.
			.when = .nextwhen
			// Move t to the right position.
			dodeltimer0()
			doaddtimer(, )
			if !.status.CompareAndSwap(timerMoving, timerWaiting) {
				badTimer()
			}
		default:
			// Head of timers does not need adjustment.
			return
		}
	}
}

// moveTimers moves a slice of timers to pp. The slice has been taken
// from a different P.
// This is currently called when the world is stopped, but the caller
// is expected to have locked the timers for pp.
func moveTimers( *p,  []*timer) {
	for ,  := range  {
	:
		for {
			switch  := .status.Load();  {
			case timerWaiting:
				if !.status.CompareAndSwap(, timerMoving) {
					continue
				}
				.pp = 0
				doaddtimer(, )
				if !.status.CompareAndSwap(timerMoving, timerWaiting) {
					badTimer()
				}
				break 
			case timerModifiedEarlier, timerModifiedLater:
				if !.status.CompareAndSwap(, timerMoving) {
					continue
				}
				.when = .nextwhen
				.pp = 0
				doaddtimer(, )
				if !.status.CompareAndSwap(timerMoving, timerWaiting) {
					badTimer()
				}
				break 
			case timerDeleted:
				if !.status.CompareAndSwap(, timerRemoved) {
					continue
				}
				.pp = 0
				// We no longer need this timer in the heap.
				break 
			case timerModifying:
				// Loop until the modification is complete.
				osyield()
			case timerNoStatus, timerRemoved:
				// We should not see these status values in a timers heap.
				badTimer()
			case timerRunning, timerRemoving, timerMoving:
				// Some other P thinks it owns this timer,
				// which should not happen.
				badTimer()
			default:
				badTimer()
			}
		}
	}
}

// adjusttimers looks through the timers in the current P's heap for
// any timers that have been modified to run earlier, and puts them in
// the correct place in the heap. While looking for those timers,
// it also moves timers that have been modified to run later,
// and removes deleted timers. The caller must have locked the timers for pp.
func adjusttimers( *p,  int64) {
	// If we haven't yet reached the time of the first timerModifiedEarlier
	// timer, don't do anything. This speeds up programs that adjust
	// a lot of timers back and forth if the timers rarely expire.
	// We'll postpone looking through all the adjusted timers until
	// one would actually expire.
	 := .timerModifiedEarliest.Load()
	if  == 0 ||  >  {
		if verifyTimers {
			verifyTimerHeap()
		}
		return
	}

	// We are going to clear all timerModifiedEarlier timers.
	.timerModifiedEarliest.Store(0)

	var  []*timer
	for  := 0;  < len(.timers); ++ {
		 := .timers[]
		if .pp.ptr() !=  {
			throw("adjusttimers: bad p")
		}
		switch  := .status.Load();  {
		case timerDeleted:
			if .status.CompareAndSwap(, timerRemoving) {
				 := dodeltimer(, )
				if !.status.CompareAndSwap(timerRemoving, timerRemoved) {
					badTimer()
				}
				.deletedTimers.Add(-1)
				// Go back to the earliest changed heap entry.
				// "- 1" because the loop will add 1.
				 =  - 1
			}
		case timerModifiedEarlier, timerModifiedLater:
			if .status.CompareAndSwap(, timerMoving) {
				// Now we can change the when field.
				.when = .nextwhen
				// Take t off the heap, and hold onto it.
				// We don't add it back yet because the
				// heap manipulation could cause our
				// loop to skip some other timer.
				 := dodeltimer(, )
				 = append(, )
				// Go back to the earliest changed heap entry.
				// "- 1" because the loop will add 1.
				 =  - 1
			}
		case timerNoStatus, timerRunning, timerRemoving, timerRemoved, timerMoving:
			badTimer()
		case timerWaiting:
			// OK, nothing to do.
		case timerModifying:
			// Check again after modification is complete.
			osyield()
			--
		default:
			badTimer()
		}
	}

	if len() > 0 {
		addAdjustedTimers(, )
	}

	if verifyTimers {
		verifyTimerHeap()
	}
}

// addAdjustedTimers adds any timers we adjusted in adjusttimers
// back to the timer heap.
func addAdjustedTimers( *p,  []*timer) {
	for ,  := range  {
		doaddtimer(, )
		if !.status.CompareAndSwap(timerMoving, timerWaiting) {
			badTimer()
		}
	}
}

// nobarrierWakeTime looks at P's timers and returns the time when we
// should wake up the netpoller. It returns 0 if there are no timers.
// This function is invoked when dropping a P, and must run without
// any write barriers.
//
//go:nowritebarrierrec
func nobarrierWakeTime( *p) int64 {
	 := .timer0When.Load()
	 := .timerModifiedEarliest.Load()
	if  == 0 || ( != 0 &&  < ) {
		 = 
	}
	return 
}

// runtimer examines the first timer in timers. If it is ready based on now,
// it runs the timer and removes or updates it.
// Returns 0 if it ran a timer, -1 if there are no more timers, or the time
// when the first timer should run.
// The caller must have locked the timers for pp.
// If a timer is run, this will temporarily unlock the timers.
//
//go:systemstack
func runtimer( *p,  int64) int64 {
	for {
		 := .timers[0]
		if .pp.ptr() !=  {
			throw("runtimer: bad p")
		}
		switch  := .status.Load();  {
		case timerWaiting:
			if .when >  {
				// Not ready to run.
				return .when
			}

			if !.status.CompareAndSwap(, timerRunning) {
				continue
			}
			// Note that runOneTimer may temporarily unlock
			// pp.timersLock.
			runOneTimer(, , )
			return 0

		case timerDeleted:
			if !.status.CompareAndSwap(, timerRemoving) {
				continue
			}
			dodeltimer0()
			if !.status.CompareAndSwap(timerRemoving, timerRemoved) {
				badTimer()
			}
			.deletedTimers.Add(-1)
			if len(.timers) == 0 {
				return -1
			}

		case timerModifiedEarlier, timerModifiedLater:
			if !.status.CompareAndSwap(, timerMoving) {
				continue
			}
			.when = .nextwhen
			dodeltimer0()
			doaddtimer(, )
			if !.status.CompareAndSwap(timerMoving, timerWaiting) {
				badTimer()
			}

		case timerModifying:
			// Wait for modification to complete.
			osyield()

		case timerNoStatus, timerRemoved:
			// Should not see a new or inactive timer on the heap.
			badTimer()
		case timerRunning, timerRemoving, timerMoving:
			// These should only be set when timers are locked,
			// and we didn't do it.
			badTimer()
		default:
			badTimer()
		}
	}
}

// runOneTimer runs a single timer.
// The caller must have locked the timers for pp.
// This will temporarily unlock the timers while running the timer function.
//
//go:systemstack
func runOneTimer( *p,  *timer,  int64) {
	if raceenabled {
		 := getg().m.p.ptr()
		if .timerRaceCtx == 0 {
			.timerRaceCtx = racegostart(abi.FuncPCABIInternal(runtimer) + sys.PCQuantum)
		}
		raceacquirectx(.timerRaceCtx, unsafe.Pointer())
	}

	 := .f
	 := .arg
	 := .seq

	if .period > 0 {
		// Leave in heap but adjust next time to fire.
		 := .when - 
		.when += .period * (1 + -/.period)
		if .when < 0 { // check for overflow.
			.when = maxWhen
		}
		siftdownTimer(.timers, 0)
		if !.status.CompareAndSwap(timerRunning, timerWaiting) {
			badTimer()
		}
		updateTimer0When()
	} else {
		// Remove from heap.
		dodeltimer0()
		if !.status.CompareAndSwap(timerRunning, timerNoStatus) {
			badTimer()
		}
	}

	if raceenabled {
		// Temporarily use the current P's racectx for g0.
		 := getg()
		if .racectx != 0 {
			throw("runOneTimer: unexpected racectx")
		}
		.racectx = .m.p.ptr().timerRaceCtx
	}

	unlock(&.timersLock)

	(, )

	lock(&.timersLock)

	if raceenabled {
		 := getg()
		.racectx = 0
	}
}

// clearDeletedTimers removes all deleted timers from the P's timer heap.
// This is used to avoid clogging up the heap if the program
// starts a lot of long-running timers and then stops them.
// For example, this can happen via context.WithTimeout.
//
// This is the only function that walks through the entire timer heap,
// other than moveTimers which only runs when the world is stopped.
//
// The caller must have locked the timers for pp.
func clearDeletedTimers( *p) {
	// We are going to clear all timerModifiedEarlier timers.
	// Do this now in case new ones show up while we are looping.
	.timerModifiedEarliest.Store(0)

	 := int32(0)
	 := 0
	 := false
	 := .timers
:
	for ,  := range  {
		for {
			switch  := .status.Load();  {
			case timerWaiting:
				if  {
					[] = 
					siftupTimer(, )
				}
				++
				continue 
			case timerModifiedEarlier, timerModifiedLater:
				if .status.CompareAndSwap(, timerMoving) {
					.when = .nextwhen
					[] = 
					siftupTimer(, )
					++
					 = true
					if !.status.CompareAndSwap(timerMoving, timerWaiting) {
						badTimer()
					}
					continue 
				}
			case timerDeleted:
				if .status.CompareAndSwap(, timerRemoving) {
					.pp = 0
					++
					if !.status.CompareAndSwap(timerRemoving, timerRemoved) {
						badTimer()
					}
					 = true
					continue 
				}
			case timerModifying:
				// Loop until modification complete.
				osyield()
			case timerNoStatus, timerRemoved:
				// We should not see these status values in a timer heap.
				badTimer()
			case timerRunning, timerRemoving, timerMoving:
				// Some other P thinks it owns this timer,
				// which should not happen.
				badTimer()
			default:
				badTimer()
			}
		}
	}

	// Set remaining slots in timers slice to nil,
	// so that the timer values can be garbage collected.
	for  := ;  < len(); ++ {
		[] = nil
	}

	.deletedTimers.Add(-)
	.numTimers.Add(-)

	 = [:]
	.timers = 
	updateTimer0When()

	if verifyTimers {
		verifyTimerHeap()
	}
}

// verifyTimerHeap verifies that the timer heap is in a valid state.
// This is only for debugging, and is only called if verifyTimers is true.
// The caller must have locked the timers.
func verifyTimerHeap( *p) {
	for ,  := range .timers {
		if  == 0 {
			// First timer has no parent.
			continue
		}

		// The heap is 4-ary. See siftupTimer and siftdownTimer.
		 := ( - 1) / 4
		if .when < .timers[].when {
			print("bad timer heap at ", , ": ", , ": ", .timers[].when, ", ", , ": ", .when, "\n")
			throw("bad timer heap")
		}
	}
	if  := int(.numTimers.Load()); len(.timers) !=  {
		println("timer heap len", len(.timers), "!= numTimers", )
		throw("bad timer heap len")
	}
}

// updateTimer0When sets the P's timer0When field.
// The caller must have locked the timers for pp.
func updateTimer0When( *p) {
	if len(.timers) == 0 {
		.timer0When.Store(0)
	} else {
		.timer0When.Store(.timers[0].when)
	}
}

// updateTimerModifiedEarliest updates the recorded nextwhen field of the
// earlier timerModifiedEarier value.
// The timers for pp will not be locked.
func updateTimerModifiedEarliest( *p,  int64) {
	for {
		 := .timerModifiedEarliest.Load()
		if  != 0 &&  <  {
			return
		}

		if .timerModifiedEarliest.CompareAndSwap(, ) {
			return
		}
	}
}

// timeSleepUntil returns the time when the next timer should fire. Returns
// maxWhen if there are no timers.
// This is only called by sysmon and checkdead.
func timeSleepUntil() int64 {
	 := int64(maxWhen)

	// Prevent allp slice changes. This is like retake.
	lock(&allpLock)
	for ,  := range allp {
		if  == nil {
			// This can happen if procresize has grown
			// allp but not yet created new Ps.
			continue
		}

		 := .timer0When.Load()
		if  != 0 &&  <  {
			 = 
		}

		 = .timerModifiedEarliest.Load()
		if  != 0 &&  <  {
			 = 
		}
	}
	unlock(&allpLock)

	return 
}

// Heap maintenance algorithms.
// These algorithms check for slice index errors manually.
// Slice index error can happen if the program is using racy
// access to timers. We don't want to panic here, because
// it will cause the program to crash with a mysterious
// "panic holding locks" message. Instead, we panic while not
// holding a lock.

// siftupTimer puts the timer at position i in the right place
// in the heap by moving it up toward the top of the heap.
// It returns the smallest changed index.
func siftupTimer( []*timer,  int) int {
	if  >= len() {
		badTimer()
	}
	 := [].when
	if  <= 0 {
		badTimer()
	}
	 := []
	for  > 0 {
		 := ( - 1) / 4 // parent
		if  >= [].when {
			break
		}
		[] = []
		 = 
	}
	if  != [] {
		[] = 
	}
	return 
}

// siftdownTimer puts the timer at position i in the right place
// in the heap by moving it down toward the bottom of the heap.
func siftdownTimer( []*timer,  int) {
	 := len()
	if  >=  {
		badTimer()
	}
	 := [].when
	if  <= 0 {
		badTimer()
	}
	 := []
	for {
		 := *4 + 1 // left child
		 :=  + 2  // mid child
		if  >=  {
			break
		}
		 := [].when
		if +1 <  && [+1].when <  {
			 = [+1].when
			++
		}
		if  <  {
			 := [].when
			if +1 <  && [+1].when <  {
				 = [+1].when
				++
			}
			if  <  {
				 = 
				 = 
			}
		}
		if  >=  {
			break
		}
		[] = []
		 = 
	}
	if  != [] {
		[] = 
	}
}

// badTimer is called if the timer data structures have been corrupted,
// presumably due to racy use by the program. We panic here rather than
// panicking due to invalid slice access while holding locks.
// See issue #25686.
func badTimer() {
	throw("timer data corruption")
}