Browse Source

Update examples to use time types

Closes: #141
Approved by: whitequark
Dan Robertson 7 years ago
parent
commit
8e74fce11d
7 changed files with 70 additions and 70 deletions
  1. 13 8
      examples/benchmark.rs
  2. 2 4
      examples/client.rs
  3. 2 3
      examples/httpclient.rs
  4. 16 14
      examples/loopback.rs
  5. 30 24
      examples/ping.rs
  6. 2 4
      examples/server.rs
  7. 5 13
      examples/utils.rs

+ 13 - 8
examples/benchmark.rs

@@ -11,7 +11,6 @@ mod utils;
 use std::cmp;
 use std::collections::BTreeMap;
 use std::sync::atomic::{Ordering, AtomicBool, ATOMIC_BOOL_INIT};
-use std::time::Instant;
 use std::thread;
 use std::io::{Read, Write};
 use std::net::TcpStream;
@@ -21,6 +20,7 @@ use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
 use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder};
 use smoltcp::socket::SocketSet;
 use smoltcp::socket::{TcpSocket, TcpSocketBuffer};
+use smoltcp::time::{Duration, Instant};
 
 const AMOUNT: usize = 1_000_000_000;
 
@@ -52,9 +52,7 @@ fn client(kind: Client) {
 
     let end = Instant::now();
 
-    let elapsed = end - start;
-    let elapsed = elapsed.as_secs() as f64
-                + elapsed.subsec_nanos() as f64 * 1e-9;
+    let elapsed = (end - start).total_millis() as f64 / 1000.0;
 
     println!("throughput: {:.3} Gbps", AMOUNT as f64 / elapsed / 0.125e9);
 
@@ -84,8 +82,6 @@ fn main() {
 
     thread::spawn(move || client(mode));
 
-    let startup_time = Instant::now();
-
     let neighbor_cache = NeighborCache::new(BTreeMap::new());
 
     let tcp1_rx_buffer = TcpSocketBuffer::new(vec![0; 65535]);
@@ -107,10 +103,11 @@ fn main() {
     let mut sockets = SocketSet::new(vec![]);
     let tcp1_handle = sockets.add(tcp1_socket);
     let tcp2_handle = sockets.add(tcp2_socket);
+    let default_timeout = Some(Duration::from_millis(1000));
 
     let mut processed = 0;
     while !CLIENT_DONE.load(Ordering::SeqCst) {
-        let timestamp = utils::millis_since(startup_time);
+        let timestamp = Instant::now();
         iface.poll(&mut sockets, timestamp).expect("poll error");
 
         // tcp:1234: emit data
@@ -149,6 +146,14 @@ fn main() {
             }
         }
 
-        phy_wait(fd, iface.poll_delay(&sockets, timestamp).or(Some(1000))).expect("wait error");
+        match iface.poll_at(&sockets, timestamp) {
+            Some(poll_at) if timestamp < poll_at => {
+                phy_wait(fd, Some(poll_at - timestamp)).expect("wait error");
+            },
+            Some(_) => (),
+            None => {
+                phy_wait(fd, default_timeout).expect("wait error");
+            }
+        }
     }
 }

+ 2 - 4
examples/client.rs

@@ -8,12 +8,12 @@ mod utils;
 
 use std::str::{self, FromStr};
 use std::collections::BTreeMap;
-use std::time::Instant;
 use std::os::unix::io::AsRawFd;
 use smoltcp::phy::wait as phy_wait;
 use smoltcp::wire::{EthernetAddress, Ipv4Address, IpAddress, IpCidr};
 use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder};
 use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer};
+use smoltcp::time::Instant;
 
 fn main() {
     utils::setup_logging("");
@@ -31,8 +31,6 @@ fn main() {
     let address = IpAddress::from_str(&matches.free[0]).expect("invalid address format");
     let port = u16::from_str(&matches.free[1]).expect("invalid port format");
 
-    let startup_time = Instant::now();
-
     let neighbor_cache = NeighborCache::new(BTreeMap::new());
 
     let tcp_rx_buffer = TcpSocketBuffer::new(vec![0; 64]);
@@ -59,7 +57,7 @@ fn main() {
 
     let mut tcp_active = false;
     loop {
-        let timestamp = utils::millis_since(startup_time);
+        let timestamp = Instant::now();
         iface.poll(&mut sockets, timestamp).expect("poll error");
 
         {

+ 2 - 3
examples/httpclient.rs

@@ -10,13 +10,13 @@ mod utils;
 
 use std::str::{self, FromStr};
 use std::collections::BTreeMap;
-use std::time::Instant;
 use std::os::unix::io::AsRawFd;
 use url::Url;
 use smoltcp::phy::wait as phy_wait;
 use smoltcp::wire::{EthernetAddress, Ipv4Address, IpAddress, IpCidr};
 use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder};
 use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer};
+use smoltcp::time::Instant;
 
 fn main() {
     utils::setup_logging("");
@@ -34,7 +34,6 @@ fn main() {
     let address = IpAddress::from_str(&matches.free[0]).expect("invalid address format");
     let url = Url::parse(&matches.free[1]).expect("invalid url format");
 
-    let startup_time = Instant::now();
 
     let neighbor_cache = NeighborCache::new(BTreeMap::new());
 
@@ -59,7 +58,7 @@ fn main() {
     let mut state = State::Connect;
 
     loop {
-        let timestamp = utils::millis_since(startup_time);
+        let timestamp = Instant::now();
         iface.poll(&mut sockets, timestamp).expect("poll error");
 
         {

+ 16 - 14
examples/loopback.rs

@@ -20,24 +20,26 @@ use smoltcp::phy::Loopback;
 use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
 use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder};
 use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer};
+use smoltcp::time::{Duration, Instant};
 
 #[cfg(not(feature = "std"))]
 mod mock {
+    use smoltcp::time::{Duration, Instant};
     use core::cell::Cell;
 
     #[derive(Debug)]
-    pub struct Clock(Cell<u64>);
+    pub struct Clock(Cell<Instant>);
 
     impl Clock {
         pub fn new() -> Clock {
-            Clock(Cell::new(0))
+            Clock(Cell::new(Instant::from_millis(0)))
         }
 
-        pub fn advance(&self, millis: u64) {
-            self.0.set(self.0.get() + millis)
+        pub fn advance(&self, duration: Duration) {
+            self.0.set(self.0.get() + duration)
         }
 
-        pub fn elapsed(&self) -> u64 {
+        pub fn elapsed(&self) -> Instant {
             self.0.get()
         }
     }
@@ -47,6 +49,7 @@ mod mock {
 mod mock {
     use std::sync::Arc;
     use std::sync::atomic::{Ordering, AtomicUsize};
+	use smoltcp::time::{Duration, Instant};
 
     // should be AtomicU64 but that's unstable
     #[derive(Debug, Clone)]
@@ -57,12 +60,12 @@ mod mock {
             Clock(Arc::new(AtomicUsize::new(0)))
         }
 
-        pub fn advance(&self, millis: u64) {
-            self.0.fetch_add(millis as usize, Ordering::SeqCst);
+        pub fn advance(&self, duration: Duration) {
+            self.0.fetch_add(duration.total_millis() as usize, Ordering::SeqCst);
         }
 
-        pub fn elapsed(&self) -> u64 {
-            self.0.load(Ordering::SeqCst) as u64
+        pub fn elapsed(&self) -> Instant {
+            Instant::from_millis(self.0.load(Ordering::SeqCst) as i64)
         }
     }
 }
@@ -123,7 +126,7 @@ fn main() {
     let mut did_listen  = false;
     let mut did_connect = false;
     let mut done = false;
-    while !done && clock.elapsed() < 10_000 {
+    while !done && clock.elapsed() < Instant::from_millis(10_000) {
         iface.poll(&mut socket_set, clock.elapsed()).expect("poll error");
 
         {
@@ -164,13 +167,12 @@ fn main() {
         }
 
         match iface.poll_delay(&socket_set, clock.elapsed()) {
-            Some(0) =>
-                debug!("resuming"),
+            Some(Duration { millis: 0 }) => debug!("resuming"),
             Some(delay) => {
                 debug!("sleeping for {} ms", delay);
                 clock.advance(delay)
-            }
-            None => clock.advance(1)
+            },
+            None => clock.advance(Duration::from_millis(1))
         }
     }
 

+ 30 - 24
examples/ping.rs

@@ -9,8 +9,9 @@ mod utils;
 
 use std::str::FromStr;
 use std::collections::BTreeMap;
-use std::time::Instant;
+use std::cmp;
 use std::os::unix::io::AsRawFd;
+use smoltcp::time::{Duration, Instant};
 use smoltcp::phy::Device;
 use smoltcp::phy::wait as phy_wait;
 use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr,
@@ -41,10 +42,12 @@ fn main() {
     let device_caps = device.capabilities();
     let address  = Ipv4Address::from_str(&matches.free[0]).expect("invalid address format");
     let count    = matches.opt_str("count").map(|s| usize::from_str(&s).unwrap()).unwrap_or(4);
-    let interval = matches.opt_str("interval").map(|s| u64::from_str(&s).unwrap()).unwrap_or(1);
-    let timeout  = matches.opt_str("timeout").map(|s| u64::from_str(&s).unwrap()).unwrap_or(5);
-
-    let startup_time = Instant::now();
+    let interval = matches.opt_str("interval")
+        .map(|s| Duration::from_secs(u64::from_str(&s).unwrap()))
+        .unwrap_or(Duration::from_secs(1));
+    let timeout  = Duration::from_secs(
+        matches.opt_str("timeout").map(|s| u64::from_str(&s).unwrap()).unwrap_or(5)
+    );
 
     let neighbor_cache = NeighborCache::new(BTreeMap::new());
 
@@ -68,7 +71,7 @@ fn main() {
     let mut sockets = SocketSet::new(vec![]);
     let icmp_handle = sockets.add(icmp_socket);
 
-    let mut send_at = 0;
+    let mut send_at = Instant::from_millis(0);
     let mut seq_no = 0;
     let mut received = 0;
     let mut echo_payload = [0xffu8; 40];
@@ -77,22 +80,19 @@ fn main() {
     let endpoint = IpAddress::Ipv4(remote_addr);
 
     loop {
-        let timestamp = utils::millis_since(startup_time);
-        iface.poll(&mut sockets, timestamp).expect("poll error");
+        iface.poll(&mut sockets, Instant::now()).unwrap();
 
         {
+            let timestamp = Instant::now();
             let mut socket = sockets.get::<IcmpSocket>(icmp_handle);
             if !socket.is_open() {
-                socket.bind(IcmpEndpoint::Ident(ident)).unwrap()
+                socket.bind(IcmpEndpoint::Ident(ident)).unwrap();
+                send_at = timestamp;
             }
 
-            let timestamp = Instant::now().duration_since(startup_time);
-            let timestamp_us = (timestamp.as_secs() * 1000000) +
-                (timestamp.subsec_nanos() / 1000) as u64;
-
             if socket.can_send() && seq_no < count as u16 &&
-                    send_at <= utils::millis_since(startup_time) {
-                NetworkEndian::write_u64(&mut echo_payload, timestamp_us);
+                    send_at <= timestamp {
+                NetworkEndian::write_i64(&mut echo_payload, timestamp.total_millis());
                 let icmp_repr = Icmpv4Repr::EchoRequest {
                     ident: ident,
                     seq_no,
@@ -108,7 +108,7 @@ fn main() {
 
                 waiting_queue.insert(seq_no, timestamp);
                 seq_no += 1;
-                send_at += interval * 1000;
+                send_at += interval;
             }
 
             if socket.can_recv() {
@@ -118,10 +118,10 @@ fn main() {
 
                 if let Icmpv4Repr::EchoReply { seq_no, data, .. } = icmp_repr {
                     if let Some(_) = waiting_queue.get(&seq_no) {
-                        let packet_timestamp_us = NetworkEndian::read_u64(data);
+                        let packet_timestamp_us = NetworkEndian::read_i64(data);
                         println!("{} bytes from {}: icmp_seq={}, time={:.3}ms",
                                  data.len(), remote_addr, seq_no,
-                                 (timestamp_us - packet_timestamp_us) as f64 / 1000.0);
+                                 (timestamp.total_millis() - packet_timestamp_us) as f64 / 1000.0);
                         waiting_queue.remove(&seq_no);
                         received += 1;
                     }
@@ -129,7 +129,7 @@ fn main() {
             }
 
             waiting_queue.retain(|seq, from| {
-                if (timestamp - *from).as_secs() < timeout {
+                if timestamp - *from < timeout {
                     true
                 } else {
                     println!("From {} icmp_seq={} timeout", remote_addr, seq);
@@ -142,11 +142,17 @@ fn main() {
             }
         }
 
-        let timestamp = utils::millis_since(startup_time);
-
-        let poll_at = iface.poll_at(&sockets, timestamp);
-        let resume_at = [poll_at, Some(send_at)].iter().flat_map(|x| *x).min();
-        phy_wait(fd, resume_at.map(|at| at.saturating_sub(timestamp))).expect("wait error");
+        let timestamp = Instant::now();
+        match iface.poll_at(&sockets, timestamp) {
+            Some(poll_at) if timestamp < poll_at => {
+                let resume_at = cmp::min(poll_at, send_at);
+                phy_wait(fd, Some(resume_at - timestamp)).expect("wait error");
+            },
+            Some(_) => (),
+            None => {
+                phy_wait(fd, Some(send_at - timestamp)).expect("wait error");
+            }
+        }
     }
 
     println!("--- {} ping statistics ---", remote_addr);

+ 2 - 4
examples/server.rs

@@ -9,7 +9,6 @@ mod utils;
 use std::str;
 use std::collections::BTreeMap;
 use std::fmt::Write;
-use std::time::Instant;
 use std::os::unix::io::AsRawFd;
 use smoltcp::phy::wait as phy_wait;
 use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
@@ -17,6 +16,7 @@ use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder};
 use smoltcp::socket::SocketSet;
 use smoltcp::socket::{UdpSocket, UdpSocketBuffer, UdpPacketBuffer};
 use smoltcp::socket::{TcpSocket, TcpSocketBuffer};
+use smoltcp::time::Instant;
 
 fn main() {
     utils::setup_logging("");
@@ -30,8 +30,6 @@ fn main() {
     let fd = device.as_raw_fd();
     let device = utils::parse_middleware_options(&mut matches, device, /*loopback=*/false);
 
-    let startup_time = Instant::now();
-
     let neighbor_cache = NeighborCache::new(BTreeMap::new());
 
     let udp_rx_buffer = UdpSocketBuffer::new(vec![UdpPacketBuffer::new(vec![0; 64])]);
@@ -71,7 +69,7 @@ fn main() {
 
     let mut tcp_6970_active = false;
     loop {
-        let timestamp = utils::millis_since(startup_time);
+        let timestamp = Instant::now();
         iface.poll(&mut sockets, timestamp).expect("poll error");
 
         // udp:6969: respond "hello"

+ 5 - 13
examples/utils.rs

@@ -5,7 +5,7 @@ use std::str::{self, FromStr};
 use std::rc::Rc;
 use std::io;
 use std::fs::File;
-use std::time::{Instant, SystemTime, UNIX_EPOCH};
+use std::time::{SystemTime, UNIX_EPOCH};
 use std::env;
 use std::process;
 #[cfg(feature = "log")]
@@ -18,14 +18,15 @@ use smoltcp::phy::{Device, EthernetTracer, FaultInjector};
 #[cfg(feature = "phy-tap_interface")]
 use smoltcp::phy::TapInterface;
 use smoltcp::phy::{PcapWriter, PcapSink, PcapMode, PcapLinkType};
+use smoltcp::time::Instant;
 
 #[cfg(feature = "log")]
 pub fn setup_logging_with_clock<F>(filter: &str, since_startup: F)
-        where F: Fn() -> u64 + Send + Sync + 'static {
+        where F: Fn() -> Instant + Send + Sync + 'static {
     LogBuilder::new()
         .format(move |record: &LogRecord| {
             let elapsed = since_startup();
-            let timestamp = format!("[{:6}.{:03}s]", elapsed / 1000, elapsed % 1000);
+            let timestamp = format!("[{}]", elapsed);
             if record.target().starts_with("smoltcp::") {
                 format!("\x1b[0m{} ({}): {}\x1b[0m", timestamp,
                         record.target().replace("smoltcp::", ""), record.args())
@@ -47,10 +48,8 @@ pub fn setup_logging_with_clock<F>(filter: &str, since_startup: F)
 
 #[cfg(feature = "log")]
 pub fn setup_logging(filter: &str) {
-    let startup_at = Instant::now();
     setup_logging_with_clock(filter, move  || {
-        let elapsed = Instant::now().duration_since(startup_at);
-        elapsed.as_secs() * 1000 + (elapsed.subsec_nanos() / 1000000) as u64
+        Instant::now()
     })
 }
 
@@ -142,10 +141,3 @@ pub fn parse_middleware_options<D>(matches: &mut Matches, device: D, loopback: b
     device.set_bucket_interval(shaping_interval);
     device
 }
-
-pub fn millis_since(startup_time: Instant) -> u64 {
-    let duration = Instant::now().duration_since(startup_time);
-    let duration_ms = (duration.as_secs() * 1000) +
-        (duration.subsec_nanos() / 1000000) as u64;
-    duration_ms
-}