Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to Functions to include inline and moved benches to criterion to use stable toolchain #555

Merged
merged 2 commits into from Apr 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 19 additions & 0 deletions pnet_macros/src/decorator.rs
Expand Up @@ -67,6 +67,7 @@ impl Packet {
}
}

#[inline]
pub fn generate_packet(
s: &syn::DataStruct,
name: String,
Expand All @@ -91,6 +92,7 @@ pub fn generate_packet(
Ok(tts)
}

#[inline]
fn generate_packet_struct(packet: &Packet) -> proc_macro2::TokenStream {
let items = &[
(packet.packet_name(), "PacketData"),
Expand All @@ -115,6 +117,7 @@ fn generate_packet_struct(packet: &Packet) -> proc_macro2::TokenStream {
}
}

#[inline]
fn make_type(ty_str: String, endianness_important: bool) -> Result<Type, String> {
if let Some((size, endianness, spec)) = parse_ty(&ty_str[..]) {
if !endianness_important || size <= 8 || spec == EndiannessSpecified::Yes {
Expand All @@ -138,6 +141,7 @@ fn make_type(ty_str: String, endianness_important: bool) -> Result<Type, String>
}
}

#[inline]
fn make_packet(s: &syn::DataStruct, name: String) -> Result<Packet, Error> {
let mut fields = Vec::new();
let mut payload_span = None;
Expand Down Expand Up @@ -351,6 +355,7 @@ fn make_packet(s: &syn::DataStruct, name: String) -> Result<Packet, Error> {
}

/// Return the processed length expression for a packet.
#[inline]
fn parse_length_expr(
tts: &[proc_macro2::TokenTree],
field_names: &[String],
Expand Down Expand Up @@ -423,6 +428,7 @@ fn parse_length_expr(
Ok(tokens_packet)
}

#[inline]
fn generate_packet_impl(
packet: &Packet,
mutable: bool,
Expand Down Expand Up @@ -644,6 +650,7 @@ fn generate_packet_impl(
))
}

#[inline]
fn generate_packet_impls(
packet: &Packet,
) -> Result<(proc_macro2::TokenStream, PayloadBounds, String), Error> {
Expand All @@ -663,6 +670,7 @@ fn generate_packet_impls(
.ok_or_else(|| Error::new(Span::call_site(), "generate_packet_impls failed"))
}

#[inline]
fn generate_packet_size_impls(
packet: &Packet,
size: &str,
Expand Down Expand Up @@ -690,6 +698,7 @@ fn generate_packet_size_impls(
Ok(quote! { #(#tts)* })
}

#[inline]
fn generate_packet_trait_impls(
packet: &Packet,
payload_bounds: &PayloadBounds,
Expand Down Expand Up @@ -748,6 +757,7 @@ fn generate_packet_trait_impls(
Ok(quote! { #(#tts)* })
}

#[inline]
fn generate_iterables(packet: &Packet) -> Result<proc_macro2::TokenStream, Error> {
let name = &packet.base_name;

Expand Down Expand Up @@ -795,6 +805,7 @@ fn generate_iterables(packet: &Packet) -> Result<proc_macro2::TokenStream, Error
})
}

#[inline]
fn generate_converters(packet: &Packet) -> Result<proc_macro2::TokenStream, Error> {
let get_fields = generate_get_fields(packet);

Expand Down Expand Up @@ -825,6 +836,7 @@ fn generate_converters(packet: &Packet) -> Result<proc_macro2::TokenStream, Erro
Ok(quote! { #(#tts)* })
}

#[inline]
fn generate_debug_impls(packet: &Packet) -> Result<proc_macro2::TokenStream, Error> {
let mut field_fmt_str = String::new();
let mut get_fields = String::new();
Expand Down Expand Up @@ -862,6 +874,7 @@ fn generate_debug_impls(packet: &Packet) -> Result<proc_macro2::TokenStream, Err
Ok(quote! { #(#tts)* })
}

#[inline]
fn handle_misc_field(
field: &Field,
bit_offset: &mut usize,
Expand Down Expand Up @@ -980,6 +993,7 @@ fn handle_misc_field(
Ok(())
}

#[inline]
fn handle_vec_primitive(
inner_ty_str: &str,
size: usize,
Expand Down Expand Up @@ -1088,6 +1102,7 @@ fn handle_vec_primitive(
}
}

#[inline]
fn handle_vector_field(
field: &Field,
bit_offset: &mut usize,
Expand Down Expand Up @@ -1614,6 +1629,7 @@ fn test_generate_accessor_op_str() {

/// Given the name of a field, and a set of operations required to get the value of that field,
/// return the Rust code required to get the field.
#[inline]
fn generate_accessor_str(
name: &str,
ty: &str,
Expand Down Expand Up @@ -1661,6 +1677,7 @@ fn generate_accessor_str(
accessor
}

#[inline]
fn generate_accessor_with_offset_str(
name: &str,
ty: &str,
Expand All @@ -1686,6 +1703,7 @@ fn generate_accessor_with_offset_str(
)
}

#[inline]
fn current_offset(bit_offset: usize, offset_fns: &[String]) -> String {
let base_offset = bit_offset / 8;

Expand All @@ -1694,6 +1712,7 @@ fn current_offset(bit_offset: usize, offset_fns: &[String]) -> String {
.fold(base_offset.to_string(), |a, b| a + " + " + &b[..])
}

#[inline]
fn generate_get_fields(packet: &Packet) -> String {
let mut gets = String::new();

Expand Down
12 changes: 12 additions & 0 deletions pnet_macros_support/src/packet.rs
Expand Up @@ -64,6 +64,7 @@ macro_rules! impl_index {
impl<'p> Index<$index_t> for $t<'p> {
type Output = $output_t;

#[inline]
fn index(&self, index: $index_t) -> &$output_t {
&self.as_slice().index(index)
}
Expand All @@ -74,6 +75,7 @@ macro_rules! impl_index {
macro_rules! impl_index_mut {
($t:ident, $index_t:ty, $output_t:ty) => {
impl<'p> IndexMut<$index_t> for $t<'p> {
#[inline]
fn index_mut(&mut self, index: $index_t) -> &mut $output_t {
self.as_mut_slice().index_mut(index)
}
Expand All @@ -92,6 +94,7 @@ pub enum PacketData<'p> {

impl<'p> PacketData<'p> {
/// Get a slice of the packet data.
#[inline]
pub fn as_slice(&self) -> &[u8] {
match self {
&PacketData::Owned(ref data) => data.deref(),
Expand All @@ -100,11 +103,13 @@ impl<'p> PacketData<'p> {
}

/// No-op - returns `self`.
#[inline]
pub fn to_immutable(self) -> PacketData<'p> {
self
}

/// A length of the packet data.
#[inline]
pub fn len(&self) -> usize {
self.as_slice().len()
}
Expand All @@ -127,6 +132,7 @@ pub enum MutPacketData<'p> {

impl<'p> MutPacketData<'p> {
/// Get packet data as a slice.
#[inline]
pub fn as_slice(&self) -> &[u8] {
match self {
&MutPacketData::Owned(ref data) => data.deref(),
Expand All @@ -135,6 +141,7 @@ impl<'p> MutPacketData<'p> {
}

/// Get packet data as a mutable slice.
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [u8] {
match self {
&mut MutPacketData::Owned(ref mut data) => data.deref_mut(),
Expand All @@ -143,6 +150,7 @@ impl<'p> MutPacketData<'p> {
}

/// Get an immutable version of packet data.
#[inline]
pub fn to_immutable(self) -> PacketData<'p> {
match self {
MutPacketData::Owned(data) => PacketData::Owned(data),
Expand All @@ -151,6 +159,7 @@ impl<'p> MutPacketData<'p> {
}

/// Get a length of data in the packet.
#[inline]
pub fn len(&self) -> usize {
self.as_slice().len()
}
Expand Down Expand Up @@ -179,13 +188,15 @@ pub trait PrimitiveValues {

impl PrimitiveValues for pnet_base::MacAddr {
type T = (u8, u8, u8, u8, u8, u8);
#[inline]
fn to_primitive_values(&self) -> (u8, u8, u8, u8, u8, u8) {
(self.0, self.1, self.2, self.3, self.4, self.5)
}
}

impl PrimitiveValues for ::std::net::Ipv4Addr {
type T = (u8, u8, u8, u8);
#[inline]
fn to_primitive_values(&self) -> (u8, u8, u8, u8) {
let octets = self.octets();

Expand All @@ -195,6 +206,7 @@ impl PrimitiveValues for ::std::net::Ipv4Addr {

impl PrimitiveValues for ::std::net::Ipv6Addr {
type T = (u16, u16, u16, u16, u16, u16, u16, u16);
#[inline]
fn to_primitive_values(&self) -> (u16, u16, u16, u16, u16, u16, u16, u16) {
let segments = self.segments();

Expand Down
9 changes: 9 additions & 0 deletions pnet_packet/Cargo.toml
Expand Up @@ -16,5 +16,14 @@ pnet_base = { path = "../pnet_base", version = "0.29.0" }
pnet_macros_support = { path = "../pnet_macros_support", version = "0.29.0" }
pnet_macros = { path = "../pnet_macros", version = "0.29.0" }

[dev-dependencies]
hex = "0.4.3"
criterion = {version = "0.3.5", features = ["html_reports"]} #added HTML feature becuase of the annoying warnings when running the tests

[build-dependencies]
glob = "0.3.0"

[[bench]]
name = "bench_pnet_packet"
path = "benches/packet_benchmarks.rs"
harness = false
75 changes: 75 additions & 0 deletions pnet_packet/benches/packet_benchmarks.rs
@@ -0,0 +1,75 @@
//Using criterion so that we dont need to use the test framework which requires nightly toolchain
use criterion::{criterion_group, criterion_main, Criterion, black_box};

use pnet_packet::ethernet::EthernetPacket;
use pnet_packet::ethernet::MutableEthernetPacket;
use pnet_packet::ipv4::MutableIpv4Packet;
use pnet_base::MacAddr;
use pnet_packet::Packet;
use pnet_packet::ipv4::Ipv4Packet;


fn bench_packet_new_constructor(c: &mut Criterion) {
let buffer = vec![0; 20];
c.bench_function("EthernetPacket New Packet", |b| {
b.iter(||
EthernetPacket::new(black_box(&buffer)).unwrap()
);
});
}

fn bench_packet_get_source(c: &mut Criterion) {
let buffer = vec![0; 20];
let packet = EthernetPacket::new(&buffer).unwrap();
c.bench_function("EthernetPacket Get Source", |b| {
b.iter(||
black_box(packet.get_source())
);
});
}

fn bench_packet_set_source_black_box(c: &mut Criterion) {
let mut buffer = vec![0; 20];
let mut packet = MutableEthernetPacket::new(&mut buffer).unwrap();
let mac = MacAddr::new(1, 2, 3, 4, 5, 6);
c.bench_function("EthernetPacket Set Source", |b| {
b.iter(||
packet.set_source(black_box(mac))
);
});
}

fn bench_packet_mutable_to_immutable(c: &mut Criterion) {
let mut buffer = vec![0; 20];
let mut packet = MutableEthernetPacket::new(&mut buffer).unwrap();
c.bench_function("Mutable to Immutable", |b| {
b.iter(||
black_box(packet.to_immutable())
);
});
}

fn bench_packet_immutable_to_immutable(c: &mut Criterion) {
let mut buffer = vec![0; 20];
let mut packet = EthernetPacket::new(&mut buffer).unwrap();
c.bench_function("Immutable to Immutable", |b| {
b.iter(||
black_box(packet.to_immutable())
);
});
}

fn bench_ipv4_parsing(c: &mut Criterion) {
let data = hex::decode("000c291ce319ecf4bbd93e7d08004500002e1b6540008006cd76c0a8c887c0a8c8151a3707d0dd6abb2b1f5fd25150180402120f000068656c6c6f0a").unwrap();
let ethernet = EthernetPacket::new(&data).unwrap();
let payload = ethernet.payload().clone();
c.bench_function("IPV4 Parsing", |b| {
b.iter(||
Ipv4Packet::new(black_box(&payload))
);
});
}

criterion_group!(benches, bench_packet_new_constructor, bench_packet_get_source, bench_packet_set_source_black_box, bench_packet_mutable_to_immutable, bench_packet_immutable_to_immutable, bench_ipv4_parsing);

criterion_main!(benches);
42 changes: 0 additions & 42 deletions pnet_packet/src/ethernet.rs
Expand Up @@ -171,45 +171,3 @@ fn ether_type_to_str() {
assert_eq!(format!("{}", unknown), "unknown");
}

#[cfg(all(test, feature = "benchmark"))]
mod packet_benchmarks {
use super::*;
use test::{Bencher, black_box};

use util::MacAddr;

#[bench]
fn bench_packet_new_constructor(b: &mut Bencher) {
let buffer = vec![0; 20];
b.iter(|| EthernetPacket::new(black_box(&buffer)).unwrap());
}

#[bench]
fn bench_packet_get_source(b: &mut Bencher) {
let buffer = vec![0; 20];
let packet = EthernetPacket::new(&buffer).unwrap();
b.iter(|| black_box(packet.get_source()));
}

#[bench]
fn bench_packet_set_source_black_box(b: &mut Bencher) {
let mut buffer = vec![0; 20];
let mut packet = MutableEthernetPacket::new(&mut buffer).unwrap();
let mac = MacAddr::new(1, 2, 3, 4, 5, 6);
b.iter(|| packet.set_source(black_box(mac)));
}

#[bench]
fn bench_packet_mutable_to_immutable(b: &mut Bencher) {
let mut buffer = vec![0; 20];
let mut packet = MutableEthernetPacket::new(&mut buffer).unwrap();
b.iter(|| black_box(packet.to_immutable()));
}

#[bench]
fn bench_packet_immutable_to_immutable(b: &mut Bencher) {
let mut buffer = vec![0; 20];
let mut packet = EthernetPacket::new(&mut buffer).unwrap();
b.iter(|| black_box(packet.to_immutable()));
}
}