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

Fix benchmarks #243

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 4 additions & 2 deletions benches/fs_open_close.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ pub fn run_benchmark(c: &mut Criterion) {
group.bench_function("TF01: Lind open+close", |b| {
b.iter(|| {
let fd = cage.open_syscall("foo", O_CREAT | O_TRUNC | O_WRONLY, S_IRWXA);
cage.close_syscall(fd);
assert!(fd > 2); // Ensure we didn't get an error or an odd fd
assert_eq!(cage.close_syscall(fd), 0); // close the file w/o error
})
});

Expand All @@ -55,7 +56,8 @@ pub fn run_benchmark(c: &mut Criterion) {
O_CREAT | O_TRUNC | O_WRONLY,
S_IRWXA,
);
libc::close(fd);
assert!(fd > 2); // Ensure we didn't get an error or an odd fd
assert_eq!(libc::close(fd), 0); // close the file w/o error
})
});
group.finish();
Expand Down
90 changes: 83 additions & 7 deletions benches/fs_read_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,28 +54,74 @@ pub fn run_benchmark(c: &mut Criterion) {
&String::from_utf8(vec![b'X'; *buflen]).expect("error building string"),
);

let fd = cage.open_syscall("foo", O_CREAT | O_TRUNC | O_WRONLY, S_IRWXA);
// The size of the buffer and the amount we expect to read and write.
let expected_retval = *buflen as i32;

// My current position when writing...
let mut pos = 0;

// Rather than track the file size, I will reset after a fixed amount
// of data is written. This is to avoid https://github.com/Lind-Project/safeposix-rust/issues/241
// Once that bug is fixed, I should model the code used for Native
// and just track how much write has written, using this to know when
// to reset
const RESET_LENGTH: i32 = 1024 * 1024 * 4; // 4MB

// Did I make it to the reset length? If not I will later abort so
// that I ensure I have enough to read.
let mut reached_reset_length: bool = false;

let fd = cage.open_syscall("foo", O_CREAT | O_TRUNC | O_RDWR, S_IRWXA);
// Let's see how fast various file system calls are
group.bench_with_input(
BenchmarkId::new("TF02:Lind write", buflen),
buflen,
|b, buflen| {
b.iter(|| {
let _ = cage.write_syscall(fd, deststring, *buflen);
pos += expected_retval;
// pos is the value we expect the pointer to be at AFTER
// the write, so we need < pos here to write until
// RESET_LENGTH
if RESET_LENGTH < pos {
cage.lseek_syscall(fd, 0, SEEK_SET);
pos = 0;
reached_reset_length = true;
}
assert_eq!(cage.write_syscall(fd, deststring, *buflen), expected_retval);
})
},
);

if !reached_reset_length {
panic!("Try decreasing RESET_LENGTH.\nOnly reached {}/{} bytes needed for read in Lind write.",pos,RESET_LENGTH);
}

cage.lseek_syscall(fd, 0, SEEK_SET);

// My current position when reading...
pos = 0;

let mut read_buffer = tests::sizecbuf(*buflen);

group.bench_with_input(
BenchmarkId::new("TF02:Lind read", buflen),
buflen,
|b, buflen| {
b.iter(|| {
cage.read_syscall(fd, read_buffer.as_mut_ptr(), *buflen);
// Track the file pointer so you can backtrack if you make
// it to the end of the file. This avoids having a bunch
// of garbage, 0 length reads skew the results...
// We use <= here because we can have a read go to the
// expected EOF
pos += expected_retval;
if RESET_LENGTH <= pos {
cage.lseek_syscall(fd, 0, SEEK_SET);
pos = 0;
}
assert_eq!(
cage.read_syscall(fd, read_buffer.as_mut_ptr(), *buflen),
expected_retval
);
})
},
);
Expand All @@ -91,10 +137,18 @@ pub fn run_benchmark(c: &mut Criterion) {
let fd: c_int;
let c_str = CString::new("/tmp/foo").unwrap();

// The size of the buffer and the amount we expect to read and write.
// I need to type convert this because it's a usize by default.
// I'm lazily converting with as here because it's not feasible to
// test values where usize would overflow this.
// NOTE: This has a different type than Lind, which is i32. I think
// this is likely okay.
let expected_retval = *buflen as isize;

let path = c_str.into_raw() as *const u8;

unsafe {
fd = libc::open(path, O_CREAT | O_TRUNC | O_WRONLY, S_IRWXA);
fd = libc::open(path, O_CREAT | O_TRUNC | O_RDWR, S_IRWXA);
}

let deststring = tests::str2cbuf(
Expand All @@ -107,15 +161,26 @@ pub fn run_benchmark(c: &mut Criterion) {
buflen,
|b, buflen| {
b.iter(|| unsafe {
let _ = libc::write(fd, deststring as *const c_void, *buflen);
assert_eq!(
libc::write(fd, deststring as *const c_void, *buflen),
expected_retval
);
})
},
);

// I'll read the file length so I don't overrun this with my reads...
let file_length: isize;
unsafe {
file_length = libc::lseek(fd, 0, SEEK_CUR) as isize;

// reset the file position
libc::lseek(fd, 0, SEEK_SET);
}

// My current position when reading...
let mut pos = 0;

let mut read_buffer = tests::sizecbuf(*buflen);

// For comparison let's time the native OS...
Expand All @@ -124,7 +189,18 @@ pub fn run_benchmark(c: &mut Criterion) {
buflen,
|b, buflen| {
b.iter(|| unsafe {
libc::read(fd, read_buffer.as_mut_ptr() as *mut c_void, *buflen);
// Track the file pointer so you can backtrack if you make
// it to the end of the file. This avoids having a bunch
// of garbage, 0 length reads skew the results...
pos += expected_retval;
if file_length <= pos {
libc::lseek(fd, 0, SEEK_SET);
pos = 0;
}
assert_eq!(
libc::read(fd, read_buffer.as_mut_ptr() as *mut c_void, *buflen),
expected_retval
);
})
},
);
Expand All @@ -141,7 +217,7 @@ pub fn run_benchmark(c: &mut Criterion) {
rustposix::safeposix::dispatcher::lindrustfinalize();
}

criterion_group!(name=benches;
criterion_group!(name=benches;
// Add the global settings here so we don't type it everywhere
config=global_criterion_settings::get_criterion();
targets=run_benchmark);
Expand Down
42 changes: 31 additions & 11 deletions benches/fs_read_write_seek.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,29 @@ pub fn run_benchmark(c: &mut Criterion) {

// Iterate for different buffer sizes...
for buflen in [1, 64, 1024, 65536].iter() {
let fd = cage.open_syscall("foo", O_CREAT | O_TRUNC | O_WRONLY, S_IRWXA);
let fd = cage.open_syscall("foo", O_CREAT | O_TRUNC | O_RDWR, S_IRWXA);

let deststring = tests::str2cbuf(
&String::from_utf8(vec![b'X'; *buflen]).expect("error building string"),
);

// The size of the buffer and the amount we expect to read and write.
// I need to type convert this because it's a usize by default.
// I'm lazily converting with as here because it's not feasible to
// test values where usize would overflow this.
let expected_retval = *buflen as i32;

let read_buffer = tests::sizecbuf(*buflen).as_mut_ptr();
// Let's see how fast various file system calls are
group.bench_with_input(
BenchmarkId::new("TF03:Lind write+read+lseek", buflen),
buflen,
|b, buflen| {
b.iter(|| {
let _ = cage.write_syscall(fd, deststring, *buflen);
cage.lseek_syscall(fd, 0, SEEK_SET);
cage.read_syscall(fd, read_buffer, *buflen);
cage.lseek_syscall(fd, 0, SEEK_SET);
assert_eq!(cage.write_syscall(fd, deststring, *buflen), expected_retval);
assert_eq!(cage.lseek_syscall(fd, 0, SEEK_SET), 0);
assert_eq!(cage.read_syscall(fd, read_buffer, *buflen), expected_retval);
assert_eq!(cage.lseek_syscall(fd, 0, SEEK_SET), 0);
})
},
);
Expand All @@ -83,7 +89,7 @@ pub fn run_benchmark(c: &mut Criterion) {
let path = c_str.into_raw() as *const u8;

unsafe {
fd = libc::open(path, O_CREAT | O_TRUNC | O_WRONLY, S_IRWXA);
fd = libc::open(path, O_CREAT | O_TRUNC | O_RDWR, S_IRWXA);
}

let deststring = tests::str2cbuf(
Expand All @@ -92,16 +98,30 @@ pub fn run_benchmark(c: &mut Criterion) {

let read_buffer = tests::sizecbuf(*buflen).as_mut_ptr();

// The size of the buffer and the amount we expect to read and write.
// I need to type convert this because it's a usize by default.
// I'm lazily converting with as here because it's not feasible to
// test values where usize would overflow this.
// NOTE: This has a different type than Lind, which is i32. I think
// this is likely okay.
let expected_retval = *buflen as isize;

// For comparison let's time the native OS...
group.bench_with_input(
BenchmarkId::new("TF03:Native write+read+lseek", buflen),
buflen,
|b, buflen| {
b.iter(|| unsafe {
let _ = libc::write(fd, deststring as *const c_void, *buflen);
libc::lseek(fd, 0, SEEK_SET);
libc::read(fd, read_buffer as *mut c_void, *buflen);
libc::lseek(fd, 0, SEEK_SET);
assert_eq!(
libc::write(fd, deststring as *const c_void, *buflen),
expected_retval
);
assert_eq!(libc::lseek(fd, 0, SEEK_SET), 0);
assert_eq!(
libc::read(fd, read_buffer as *mut c_void, *buflen),
expected_retval
);
assert_eq!(libc::lseek(fd, 0, SEEK_SET), 0);
})
},
);
Expand All @@ -118,7 +138,7 @@ pub fn run_benchmark(c: &mut Criterion) {
rustposix::safeposix::dispatcher::lindrustfinalize();
}

criterion_group!(name=benches;
criterion_group!(name=benches;
// Add the global settings here so we don't type it everywhere
config=global_criterion_settings::get_criterion();
targets=run_benchmark);
Expand Down
Loading