// A Ticker holds a channel that delivers “ticks” of a clock
// at intervals.
typeTickerstruct{C<-chanTime// The channel on which the ticks are delivered.
rruntimeTimer}// NewTicker returns a new Ticker containing a channel that will send
// the current time on the channel after each tick. The period of the
// ticks is specified by the duration argument. The ticker will adjust
// the time interval or drop ticks to make up for slow receivers.
// The duration d must be greater than zero; if not, NewTicker will
// panic. Stop the ticker to release associated resources.
funcNewTicker(dDuration)*Ticker{ifd<=0{panic("non-positive interval for NewTicker")}// Give the channel a 1-element time buffer.
// If the client falls behind while reading, we drop ticks
// on the floor until the client catches up.
c:=make(chanTime,1)t:=&Ticker{C:c,r:runtimeTimer{when:when(d),period:int64(d),f:sendTime,arg:c,},}startTimer(&t.r)returnt}
// /usr/local/Cellar/go/1.21.6/libexec/src/runtime/time.go
// startTimer adds t to the timer heap.
//
//go:linkname startTimer time.startTimer
funcstartTimer(t*timer){ifraceenabled{racerelease(unsafe.Pointer(t))}addtimer(t)}// 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.
funcaddtimer(t*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.
ift.when<=0{throw("timer when must be positive")}ift.period<0{throw("timer period must be non-negative")}ift.status.Load()!=timerNoStatus{throw("addtimer called with initialized timer")}t.status.Store(timerWaiting)when:=t.when// Disable preemption while using pp to avoid changing another P's heap.
mp:=acquirem()pp:=getg().m.p.ptr()lock(&pp.timersLock)cleantimers(pp)doaddtimer(pp,t)unlock(&pp.timersLock)wakeNetPoller(when)releasem(mp)}