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 }