code: func (t *TimeoutWheel) doTick() {
  	var expiredList timeoutList
  
  	ticker := time.NewTicker(t.tickInterval)
  	for range ticker.C {
  		atomic.AddUint64(&t.ticks, 1)
  
  		mtx := t.lockBucket(t.ticks)
  		if t.state != running {
  			mtx.Unlock()
  			break
  		}
  
  		bucket := &t.buckets[t.ticks&t.bucketMask]
  		timeout := bucket.head
  		bucket.lastTick = t.ticks
  
  		// find all the expired timeouts in the bucket.
  		for timeout != nil {
  			next := timeout.next
  			if timeout.deadline <= t.ticks {
  				timeout.state = timeoutExpired
  				timeout.removeLocked()
  				timeout.prependLocked(&expiredList)
  			}
  			timeout = next
  		}
  
  		mtx.Unlock()
  		if expiredList.head == nil {
  			continue
  		}
  
  		select {
  		case t.calloutCh <- expiredList:
  			expiredList.head = nil
  		default:
  		}
  	}
  
  	ticker.Stop()
  }
docs: // doTick handles the ticker goroutine of the timer system