diff --git a/src/log.rs b/src/log.rs index d239264..6dd6de0 100644 --- a/src/log.rs +++ b/src/log.rs @@ -3,9 +3,8 @@ // SPDX-License-Identifier: MPL-2.0 use log::{Level, Metadata, Record, SetLoggerError}; -use rustix::time::ClockId; -use crate::time::Time; +use crate::time::{ClockSample, Realtime}; #[derive(Clone, Copy)] pub struct SimpleLogger { @@ -19,7 +18,7 @@ impl log::Log for SimpleLogger { fn log(&self, record: &Record) { if self.enabled(record.metadata()) { - let now = Time::new(ClockId::Realtime); + let now = ClockSample::::now(); println!( "{} {:5} {}:{}: {}", now.as_secs_f64(), diff --git a/src/metrics.rs b/src/metrics.rs index e8d59ac..0caa6fa 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -4,7 +4,7 @@ use crate::settings::Settings; use crate::settings::{MeasurementType, ObservabilityProtocol}; -use crate::time::Time; +use crate::time::{ClockSample, Realtime}; use flume::{Receiver, RecvTimeoutError, Sender}; use log::{error, info, warn}; use rustix::time::ClockId; @@ -148,7 +148,7 @@ impl MetricsSender { pub fn send(&self, metric: Metric) { if let Some(ref tx) = self.tx { - let ts = Time::new(ClockId::Realtime).as_nanos(); + let ts = ClockSample::::now().as_nanos(); if tx.try_send((metric, ts)).is_err() { self.dropped.fetch_add(1, Ordering::Relaxed); } @@ -197,7 +197,7 @@ impl Metrics { Err(RecvTimeoutError::Timeout) => { let dropped = self.metrics_dropped.swap(0, Ordering::Relaxed); if dropped > 0 { - let ts = Time::new(ClockId::Realtime).as_nanos(); + let ts = ClockSample::::now().as_nanos(); batch.push((Metric::Dropped { count: dropped }, ts)); } if !batch.is_empty() { diff --git a/src/pinger_icmp.rs b/src/pinger_icmp.rs index 91f4b5a..8bc5567 100644 --- a/src/pinger_icmp.rs +++ b/src/pinger_icmp.rs @@ -10,7 +10,7 @@ use std::time::Instant; use crate::pinger::{PingError, PingListener, PingReply, PingSender}; use crate::settings::MeasurementType; -use crate::time::Time; +use crate::time::{ClockSample, Monotonic}; use icmp_socket2::Icmpv4Message; use icmp_socket2::Icmpv4Packet; use icmp_socket2::packet::WithEchoRequest; @@ -54,7 +54,7 @@ impl PingListener for PingerICMPEchoListener { } }; - let clock = Time::new(ClockId::Monotonic); + let clock = ClockSample::::now(); let time_ms = clock.to_milliseconds() as i64; let rtt = (time_ms - time_sent) as f64; @@ -85,7 +85,7 @@ impl PingListener for PingerICMPEchoListener { impl PingSender for PingerICMPEchoSender { fn craft_packet(&self, id: u16, seq: u16) -> (Icmpv4Packet, i64) { - let clock = Time::new(ClockId::Monotonic); + let clock = ClockSample::::now(); let time_ms = clock.to_milliseconds(); let payload = time_ms.to_be_bytes().to_vec(); diff --git a/src/pinger_icmp_ts.rs b/src/pinger_icmp_ts.rs index 47f0daf..6aa23be 100644 --- a/src/pinger_icmp_ts.rs +++ b/src/pinger_icmp_ts.rs @@ -7,7 +7,7 @@ use crate::pinger::{PingError, PingListener, PingReply, PingSender}; use crate::settings::MeasurementType; -use crate::time::Time; +use crate::time::{ClockSample, Realtime}; use icmp_socket2::Icmpv4Message; use icmp_socket2::Icmpv4Packet; use icmp_socket2::packet::WithTimestampRequest; @@ -66,7 +66,7 @@ impl PingListener for PingerICMPTimestampListener { } let time_since_midnight = - Time::new(ClockId::Realtime).get_time_since_midnight(); + ClockSample::::now().as_time_since_midnight(); let rtt = timestamp_delta(time_since_midnight, originate as i64) as f64; let dl_time = timestamp_delta(time_since_midnight, transmit as i64) as f64; @@ -99,7 +99,7 @@ impl PingListener for PingerICMPTimestampListener { impl PingSender for PingerICMPTimestampSender { fn craft_packet(&self, id: u16, seq: u16) -> (Icmpv4Packet, i64) { - let time_since_midnight = Time::new(ClockId::Realtime).get_time_since_midnight(); + let time_since_midnight = ClockSample::::now().as_time_since_midnight(); ( Icmpv4Packet::with_timestamp_request(id, seq, time_since_midnight as u32, 0, 0) .unwrap(), diff --git a/src/ratecontroller.rs b/src/ratecontroller.rs index fb9798a..33b8bac 100644 --- a/src/ratecontroller.rs +++ b/src/ratecontroller.rs @@ -13,7 +13,7 @@ use crate::platform::{ interface_stats_provider, traffic_control_backend, }; use crate::settings::Settings; -use crate::time::Time; +use crate::time::{ClockSample, Realtime}; use crate::util::{ArcRwLock, RwLockExt}; use flume::{Receiver, Sender}; use log::{debug, info, warn}; @@ -409,7 +409,7 @@ impl Ratecontroller { self.state_dl.current_rate = self.state_dl.next_rate; self.state_ul.current_rate = self.state_ul.next_rate; - let stats_time = Time::new(ClockId::Realtime); + let stats_time = ClockSample::::now(); debug!( "{},{},{},{},{},{},{},{}", stats_time.secs(), @@ -459,7 +459,7 @@ impl Ratecontroller { && now_t.duration_since(lastdump_t).as_secs_f64() > 300.0 { for i in 0..self.settings.advanced_settings.speed_hist_size as usize { - let hist_time = Time::new(ClockId::Realtime); + let hist_time = ClockSample::::now(); if let Err(e) = fd.write_all( format!( "{},{},{},{}\n", diff --git a/src/time.rs b/src/time.rs index 4ef9b96..7b6830b 100644 --- a/src/time.rs +++ b/src/time.rs @@ -2,27 +2,42 @@ // // SPDX-License-Identifier: MPL-2.0 -use rustix::fs::Timespec; +use std::marker::PhantomData; + use rustix::time::{ClockId, clock_gettime}; -pub struct Time { - time_s: u64, - time_ns: u64, +trait Clock { + const ID: ClockId; } -impl Time { - pub fn new(id: ClockId) -> Self { - let time: Timespec = clock_gettime(id); +pub enum Realtime {} +pub enum Monotonic {} + +impl Clock for Realtime { + const ID: ClockId = ClockId::Realtime; +} + +impl Clock for Monotonic { + const ID: ClockId = ClockId::Monotonic; +} + +pub struct ClockSample { + time_s: u64, + time_ns: u64, + _clock: PhantomData, +} + +impl ClockSample { + pub fn now() -> Self { + let time = clock_gettime(C::ID); + Self { time_s: time.tv_sec as u64, time_ns: time.tv_nsec as u64, + _clock: PhantomData, } } - pub fn get_time_since_midnight(&self) -> i64 { - (self.time_s as i64 % 86400 * 1000) + (self.time_ns as i64 / 1000000) - } - pub fn secs(&self) -> u64 { self.time_s } @@ -43,3 +58,9 @@ impl Time { (self.time_s * 1000) + (self.time_ns / 1000000) } } + +impl ClockSample { + pub fn as_time_since_midnight(&self) -> i64 { + (self.time_s as i64 % 86_400 * 1000) + self.time_ns as i64 / 1_000_000 + } +}