srt_protocol/protocol/time/timer.rs
1use core::u32;
2use std::cmp::max;
3use std::time::{Duration, Instant};
4
5//4. Timers
6//
7// UDT uses four timers to trigger different periodical events. Each
8// event has its own period and they are all independent. They use the
9// system time as origins and should process wrapping if the system time
10// wraps.
11//
12// For a certain periodical event E in UDT, suppose the time variable is
13// ET and its period is p. If E is set or reset at system time t0 (ET =
14// t0), then at any time t1, (t1 - ET >= p) is the condition to check if
15// E should be triggered.
16//
17// The four timers are ACK, NAK, EXP and SND. SND is used in the sender
18// only for rate-based packet sending (see Section 6.1), whereas the
19// other three are used in the receiver only.
20//
21// ACK is used to trigger an acknowledgement (ACK). Its period is set by
22// the congestion control module. However, UDT will send an ACK no
23// longer than every 0.01 second, even though the congestion control
24// does not need timer-based ACK. Here, 0.01 second is defined as the
25// SYN time, or synchronization time, and it affects many of the other
26// timers used in UDT.
27//
28// NAK is used to trigger a negative acknowledgement (NAK). Its period
29// is dynamically updated to 4 * RTT_+ RTTVar + SYN, where RTTVar is the
30// variance of RTT samples.
31//
32// EXP is used to trigger data packets retransmission and maintain
33// connection status. Its period is dynamically updated to 4 * RTT +
34// RTTVar + SYN.
35//
36// The recommended granularity of their periods is microseconds. The
37// system time is queried after each time bounded UDP receiving (there
38// will be additional necessary data processing time if a UDP packet is
39// received) to check if any of the ACK, NAK, or EXP event should be
40// triggered. The timeout value of UDP receiving should be at least SYN.
41//
42// In the rest of this document, a name of a time variable will be used
43// to represent the associated event, the variable itself, or the value
44// of its period, depending on the context. For example, ACK can mean
45// either the ACK event or the value of ACK period.
46#[derive(Debug)]
47pub struct Timer {
48 period: Duration,
49 last: Instant,
50}
51
52impl Timer {
53 const MIN_PERIOD: Duration = Duration::from_micros(1);
54
55 pub fn new(now: Instant, period: Duration) -> Timer {
56 Timer {
57 period: max(period, Self::MIN_PERIOD),
58 last: now,
59 }
60 }
61
62 pub fn period(&mut self) -> Duration {
63 self.period
64 }
65
66 pub fn next_instant(&self) -> Instant {
67 self.last + self.period
68 }
69
70 pub fn reset(&mut self, now: Instant) {
71 self.last = now;
72 }
73
74 pub fn set_period(&mut self, period: Duration) {
75 self.period = period;
76 }
77
78 pub fn check_expired(&mut self, now: Instant) -> Option<u32> {
79 if self.period.as_nanos() == 0 {
80 return Some(1);
81 }
82 if now >= self.next_instant() {
83 let elapsed = now - self.last;
84 let elapsed_periods = (elapsed.as_nanos() / self.period.as_nanos()) as u32;
85 self.last += self.period * elapsed_periods;
86 Some(elapsed_periods)
87 } else {
88 None
89 }
90 }
91}