Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e6d57cc
Linux: Rename `get_maximum_send_size()` -> `get_system_sendbuf_size()`
antrik Apr 10, 2016
e4f695e
Add some more tests for sizes around the maximum fragment size
antrik Apr 10, 2016
1438628
Linux: Cleanup: Remove casts between `usize` and `size_t`
antrik Apr 18, 2016
46e9f8f
Linux: Cleanup: Return `usize` instead of `ssize_t` from `UnixCmsg.re…
antrik Apr 18, 2016
d0c3938
Linux: Refactor: Move FD array assembly out of `construct_header()`
antrik Apr 9, 2016
ca14b46
Linux: Cleanup: Use mem::size_of_val() instead of manual calculation
antrik Apr 9, 2016
3a81025
Linux: Don't deduct auxiliary data size from main buffer size
antrik Apr 11, 2016
65d964e
Linux: Cleanup: Turn magic value into `RESERVED_SIZE` symbolic constant
antrik Apr 17, 2016
6d94eed
Linux: Don't over-allocate followup fragment receive buffers
antrik Apr 29, 2016
ef74247
Linux: Only deduct 32 bytes from maximum send size reported by kernel
antrik Apr 11, 2016
04ac943
Linux: Cleanup: Improve size recalculation on ENOBUFS
antrik Apr 12, 2016
f2b1a02
Linux: Refactor: Introduce `downsize()` function
antrik Apr 26, 2016
37d9bb7
Linux: Refactor: Split out `UnixSender::fragment_size()`
antrik Apr 17, 2016
1e9ac09
Linux: Cleanup: Provide a `get_max_fragment_size()` method
antrik Apr 17, 2016
e554671
Linux: Cleanup: Make `msghdr.iovec` a `*const`
antrik May 3, 2016
a43aefd
Linux: Cleanup: Move header construction right before use
antrik Apr 12, 2016
a7a1373
Linux: Refactor: Turn `construct_header()` into `send_first_fragment()`
antrik Apr 17, 2016
08dcd10
Linux: Refactor: Split out new `send_followup_fragment()` function
antrik Apr 17, 2016
06ed0c3
Linux: Cleanup: Remove no longer needed `unsafe` block
antrik Apr 17, 2016
8951014
Add benchmark tests for low-level transfers
antrik Feb 14, 2016
1769906
Linux: Drop fragment headers in favour of a total length header
antrik Feb 28, 2016
31235f6
Linux: Use separate send buffers for header and main data
antrik Feb 28, 2016
4050b26
Linux: Don't initialise memory of receive buffer
antrik Apr 7, 2016
4ef8256
Linux: Avoid copying data when receiving followup fragments
antrik Mar 20, 2016
f2536df
Linux: Use separate receive buffers for header and main message
antrik Apr 7, 2016
07fbcff
Linux: Don't check maximum send size individually for each channel
antrik Apr 8, 2016
6cf99d9
Linux: Only send a control message if necessary
antrik Apr 12, 2016
224a652
Linux: Align fragment size
antrik Apr 15, 2016
02902dd
Linux: Drop use of `byteorder`
antrik Apr 24, 2016
af0223d
Linux: Precise calculation of followup fragment size
antrik Apr 12, 2016
5f27e85
Linux: Check maximum send size up front
antrik Apr 9, 2016
0bda93a
Linux: Don't over-allocate first fragment receive buffer
antrik Apr 27, 2016
7c2466e
Linux: Cleanup: Trim `unsafe` blocks in `recv()`
antrik Apr 27, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ path = "lib.rs"

[dependencies]
bincode = ">=0.4.1, <0.6"
byteorder = "0.5"
lazy_static = "0.2"
libc = "0.2"
rand = "0.3"
serde = ">=0.6, <0.8"
serde_macros = ">=0.6, <0.8"
uuid = { version = "0.2", features = ["v4"] }

[dev-dependencies]
crossbeam = "0.2"
163 changes: 163 additions & 0 deletions benches/bench.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
#![feature(test)]

extern crate crossbeam;
extern crate ipc_channel;
extern crate test;

use ipc_channel::platform;

use std::sync::{mpsc, Mutex};

/// Allows doing multiple inner iterations per bench.iter() run.
///
/// This is mostly to amortise the overhead of spawning a thread in the benchmark
/// when sending larger messages (that might be fragmented).
///
/// Note that you need to compensate the displayed results
/// for the proportionally longer runs yourself,
/// as the benchmark framework doesn't know about the inner iterations...
const ITERATIONS: usize = 1;

fn bench_size(b: &mut test::Bencher, size: usize) {
let data: Vec<u8> = (0..size).map(|i| (i % 251) as u8).collect();
let (tx, rx) = platform::channel().unwrap();

let (wait_tx, wait_rx) = mpsc::channel();
let wait_rx = Mutex::new(wait_rx);

if size > platform::OsIpcSender::get_max_fragment_size() {
b.iter(|| {
crossbeam::scope(|scope| {
scope.spawn(|| {
let wait_rx = wait_rx.lock().unwrap();
for _ in 0..ITERATIONS {
tx.send(&data, vec![], vec![]).unwrap();
if ITERATIONS > 1 {
// Prevent beginning of the next send
// from overlapping with receive of last fragment,
// as otherwise results of runs with a large tail fragment
// are significantly skewed.
wait_rx.recv().unwrap();
}
}
});
for _ in 0..ITERATIONS {
rx.recv().unwrap();
if ITERATIONS > 1 {
wait_tx.send(()).unwrap();
}
}
// For reasons mysterious to me,
// not returning a value *from every branch*
// adds some 100 ns or so of overhead to all results --
// which is quite significant for very short tests...
0
})
});
} else {
b.iter(|| {
for _ in 0..ITERATIONS {
tx.send(&data, vec![], vec![]).unwrap();
rx.recv().unwrap();
}
0
});
}
}

#[bench]
fn size_00_1(b: &mut test::Bencher) {
bench_size(b, 1);
}
#[bench]
fn size_01_2(b: &mut test::Bencher) {
bench_size(b, 2);
}
#[bench]
fn size_02_4(b: &mut test::Bencher) {
bench_size(b, 4);
}
#[bench]
fn size_03_8(b: &mut test::Bencher) {
bench_size(b, 8);
}
#[bench]
fn size_04_16(b: &mut test::Bencher) {
bench_size(b, 16);
}
#[bench]
fn size_05_32(b: &mut test::Bencher) {
bench_size(b, 32);
}
#[bench]
fn size_06_64(b: &mut test::Bencher) {
bench_size(b, 64);
}
#[bench]
fn size_07_128(b: &mut test::Bencher) {
bench_size(b, 128);
}
#[bench]
fn size_08_256(b: &mut test::Bencher) {
bench_size(b, 256);
}
#[bench]
fn size_09_512(b: &mut test::Bencher) {
bench_size(b, 512);
}
#[bench]
fn size_10_1k(b: &mut test::Bencher) {
bench_size(b, 1 * 1024);
}
#[bench]
fn size_11_2k(b: &mut test::Bencher) {
bench_size(b, 2 * 1024);
}
#[bench]
fn size_12_4k(b: &mut test::Bencher) {
bench_size(b, 4 * 1024);
}
#[bench]
fn size_13_8k(b: &mut test::Bencher) {
bench_size(b, 8 * 1024);
}
#[bench]
fn size_14_16k(b: &mut test::Bencher) {
bench_size(b, 16 * 1024);
}
#[bench]
fn size_15_32k(b: &mut test::Bencher) {
bench_size(b, 32 * 1024);
}
#[bench]
fn size_16_64k(b: &mut test::Bencher) {
bench_size(b, 64 * 1024);
}
#[bench]
fn size_17_128k(b: &mut test::Bencher) {
bench_size(b, 128 * 1024);
}
#[bench]
fn size_18_256k(b: &mut test::Bencher) {
bench_size(b, 256 * 1024);
}
#[bench]
fn size_19_512k(b: &mut test::Bencher) {
bench_size(b, 512 * 1024);
}
#[bench]
fn size_20_1m(b: &mut test::Bencher) {
bench_size(b, 1 * 1024 * 1024);
}
#[bench]
fn size_21_2m(b: &mut test::Bencher) {
bench_size(b, 2 * 1024 * 1024);
}
#[bench]
fn size_22_4m(b: &mut test::Bencher) {
bench_size(b, 4 * 1024 * 1024);
}
#[bench]
fn size_23_8m(b: &mut test::Bencher) {
bench_size(b, 8 * 1024 * 1024);
}
1 change: 0 additions & 1 deletion lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
extern crate lazy_static;

extern crate bincode;
extern crate byteorder;
extern crate libc;
extern crate rand;
extern crate serde;
Expand Down
5 changes: 5 additions & 0 deletions platform/inprocess/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use std::fmt::{self, Debug, Formatter};
use std::cmp::{PartialEq};
use std::ops::Deref;
use std::mem;
use std::usize;

use uuid::Uuid;

Expand Down Expand Up @@ -148,6 +149,10 @@ impl MpscSender {
Ok(record.sender)
}

pub fn get_max_fragment_size() -> usize {
usize::MAX
}

pub fn send(&self,
data: &[u8],
ports: Vec<MpscChannel>,
Expand Down
Loading