// 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 never be negative; otherwise runtimer will overflow // during its delta calculation and never expire other runtime timers. if t.when < 0 { t.when = maxWhen } if t.status != timerNoStatus { throw("addtimer called with initialized timer") } t.status = timerWaiting
// doaddtimer adds t to the current P's heap. // The caller must have locked the timers for pp. funcdoaddtimer(pp *p, t *timer) { // Timers rely on the network poller, so make sure the poller // has started. if netpollInited == 0 { netpollGenericInit() }
if t.pp != 0 { throw("doaddtimer: P already set in timer") } t.pp.set(pp) i := len(pp.timers) pp.timers = append(pp.timers, t) // p上添加一个timer siftupTimer(pp.timers, i) // 堆调整算法 if t == pp.timers[0] { atomic.Store64(&pp.timer0When, uint64(t.when)) } atomic.Xadd(&pp.numTimers, 1) }
// 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. funccleantimers(pp *p) { for { iflen(pp.timers) == 0 { // 判断长度 return } t := pp.timers[0] //取第一个 if t.pp.ptr() != pp { throw("cleantimers: bad p") } switch s := atomic.Load(&t.status); s { //需要判断状态 case timerDeleted: if !atomic.Cas(&t.status, s, timerRemoving) { //非删除中 continue } dodeltimer0(pp) //移除timer0 if !atomic.Cas(&t.status, timerRemoving, timerRemoved) { badTimer() } atomic.Xadd(&pp.deletedTimers, -1) case timerModifiedEarlier, timerModifiedLater: // 修改前或者修改后的状态 if !atomic.Cas(&t.status, s, timerMoving) { continue } // Now we can change the when field. t.when = t.nextwhen // 指针后移 // Move t to the right position. dodeltimer0(pp) // 删除最底下的元素 doaddtimer(pp, t) // 重新绑定P和t的关系 if s == timerModifiedEarlier { atomic.Xadd(&pp.adjustTimers, -1) } if !atomic.Cas(&t.status, timerMoving, timerWaiting) { badTimer() } default: // Head of timers does not need adjustment. 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. funcdodeltimer0(pp *p) { if t := pp.timers[0]; t.pp.ptr() != pp { throw("dodeltimer0: wrong P") } else { t.pp = 0 } last := len(pp.timers) - 1// 获取第一个timers if last > 0 { pp.timers[0] = pp.timers[last] // 栈底--->栈顶 } pp.timers[last] = nil// 置空 pp.timers = pp.timers[:last] //重新赋值 if last > 0 { siftdownTimer(pp.timers, 0) // 重新排序 } updateTimer0When(pp) // 更新P中的when atomic.Xadd(&pp.numTimers, -1) // 更新数量 }