parent
1f9e14de71
commit
20d1dd8a4a
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
||||
{
|
||||
|
|
|
@ -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");
|
||||
|
||||
{
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue