use core::future::poll_fn;
use core::task::Poll;
use criterion::{Bencher, Criterion, Throughput, criterion_group, criterion_main};
use ethercrab::{Command, MainDevice, MainDeviceConfig, PduStorage, Timeouts};
use std::{pin::pin, time::Duration};
const DATA: [u8; 8] = [0x11u8, 0x22, 0x33, 0x44, 0xaa, 0xbb, 0xcc, 0xdd];
fn do_bench(b: &mut Bencher) {
const FRAME_OVERHEAD: usize = 28;
let storage = PduStorage::<1, { PduStorage::element_size(128) }>::new();
let (mut tx, mut rx, pdu_loop) = storage.try_split().unwrap();
let maindevice = MainDevice::new(
pdu_loop,
Timeouts {
pdu: Duration::from_millis(1000),
..Timeouts::default()
},
MainDeviceConfig::default(),
);
let mut written_packet = [0u8; { FRAME_OVERHEAD + DATA.len() }];
b.iter(|| {
let mut frame_fut =
pin!(Command::fpwr(0x5678, 0x1234).send_receive::<()>(&maindevice, &DATA));
cassette::block_on(poll_fn(|ctx| {
let _ = frame_fut.as_mut().poll(ctx);
Poll::Ready(())
}));
let frame = tx.next_sendable_frame().expect("Next frame");
frame
.send_blocking(|bytes| {
written_packet.copy_from_slice(bytes);
Ok(bytes.len())
})
.expect("TX");
written_packet[6] = 0x12;
written_packet[written_packet.len() - 2] = 1;
rx.receive_frame(&written_packet).expect("RX");
let _ = cassette::block_on(frame_fut);
})
}
pub fn tx_rx(c: &mut Criterion) {
let mut group = c.benchmark_group("pdu_loop");
group.throughput(Throughput::Elements(1));
group.bench_function("elements", do_bench);
let overhead = {
(6 + 6 + 2) +
2 +
10 +
2
};
group.throughput(Throughput::Bytes(DATA.len() as u64 + overhead));
group.bench_function("ethernet frame bytes", do_bench);
group.finish();
}
criterion_group!(pdu_loop, tx_rx);
criterion_main!(pdu_loop);