mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-09 21:43:40 +00:00
runtime: add support for time.NewTimer and time.NewTicker
This commit adds support for time.NewTimer and time.NewTicker. It also adds support for the Stop() method on time.Timer, but doesn't (yet) add support for the Reset() method. The implementation has been carefully written so that programs that don't use these timers will normally not see an increase in RAM or binary size. None of the examples in the drivers repo change as a result of this commit. This comes at the cost of slightly more complex code and possibly slower execution of the timers when they are used.
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
package runtime
|
||||
|
||||
// timerNode is an element in a linked list of timers.
|
||||
type timerNode struct {
|
||||
next *timerNode
|
||||
timer *timer
|
||||
callback func(*timerNode)
|
||||
}
|
||||
|
||||
// whenTicks returns the (absolute) time when this timer should trigger next.
|
||||
func (t *timerNode) whenTicks() timeUnit {
|
||||
return nanosecondsToTicks(t.timer.when)
|
||||
}
|
||||
|
||||
// Defined in the time package, implemented here in the runtime.
|
||||
//go:linkname startTimer time.startTimer
|
||||
func startTimer(tim *timer) {
|
||||
addTimer(&timerNode{
|
||||
timer: tim,
|
||||
callback: timerCallback,
|
||||
})
|
||||
scheduleLog("adding timer")
|
||||
}
|
||||
|
||||
// timerCallback is called when a timer expires. It makes sure to call the
|
||||
// callback in the time package and to re-add the timer to the queue if this is
|
||||
// a ticker (repeating timer).
|
||||
// This is intentionally used as a callback and not a direct call (even though a
|
||||
// direct call would be trivial), because otherwise a circular dependency
|
||||
// between scheduler, addTimer and timerQueue would form. Such a circular
|
||||
// dependency causes timerQueue not to get optimized away.
|
||||
// If timerQueue doesn't get optimized away, small programs (that don't call
|
||||
// time.NewTimer etc) would still pay the cost of these timers.
|
||||
func timerCallback(tn *timerNode) {
|
||||
// Run timer function (implemented in the time package).
|
||||
// The seq parameter to the f function is not used in the time
|
||||
// package so is left zero.
|
||||
tn.timer.f(tn.timer.arg, 0)
|
||||
|
||||
// If this is a periodic timer (a ticker), re-add it to the queue.
|
||||
if tn.timer.period != 0 {
|
||||
tn.timer.when += tn.timer.period
|
||||
addTimer(tn)
|
||||
}
|
||||
}
|
||||
|
||||
//go:linkname stopTimer time.stopTimer
|
||||
func stopTimer(tim *timer) bool {
|
||||
return removeTimer(tim)
|
||||
}
|
||||
Reference in New Issue
Block a user