github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/runtime/time.go (about)

     1  package runtime
     2  
     3  // timerNode is an element in a linked list of timers.
     4  type timerNode struct {
     5  	next     *timerNode
     6  	timer    *timer
     7  	callback func(*timerNode)
     8  }
     9  
    10  // whenTicks returns the (absolute) time when this timer should trigger next.
    11  func (t *timerNode) whenTicks() timeUnit {
    12  	return nanosecondsToTicks(t.timer.when)
    13  }
    14  
    15  // Defined in the time package, implemented here in the runtime.
    16  //
    17  //go:linkname startTimer time.startTimer
    18  func startTimer(tim *timer) {
    19  	addTimer(&timerNode{
    20  		timer:    tim,
    21  		callback: timerCallback,
    22  	})
    23  	scheduleLog("adding timer")
    24  }
    25  
    26  // timerCallback is called when a timer expires. It makes sure to call the
    27  // callback in the time package and to re-add the timer to the queue if this is
    28  // a ticker (repeating timer).
    29  // This is intentionally used as a callback and not a direct call (even though a
    30  // direct call would be trivial), because otherwise a circular dependency
    31  // between scheduler, addTimer and timerQueue would form. Such a circular
    32  // dependency causes timerQueue not to get optimized away.
    33  // If timerQueue doesn't get optimized away, small programs (that don't call
    34  // time.NewTimer etc) would still pay the cost of these timers.
    35  func timerCallback(tn *timerNode) {
    36  	// Run timer function (implemented in the time package).
    37  	// The seq parameter to the f function is not used in the time
    38  	// package so is left zero.
    39  	tn.timer.f(tn.timer.arg, 0)
    40  
    41  	// If this is a periodic timer (a ticker), re-add it to the queue.
    42  	if tn.timer.period != 0 {
    43  		tn.timer.when += tn.timer.period
    44  		addTimer(tn)
    45  	}
    46  }
    47  
    48  //go:linkname stopTimer time.stopTimer
    49  func stopTimer(tim *timer) bool {
    50  	return removeTimer(tim)
    51  }
    52  
    53  //go:linkname resetTimer time.resetTimer
    54  func resetTimer(tim *timer, when int64) bool {
    55  	tim.when = when
    56  	removed := removeTimer(tim)
    57  	startTimer(tim)
    58  	return removed
    59  }