70 lines
2.3 KiB
Rust
70 lines
2.3 KiB
Rust
// Test-only, unprivileged concurrent direct reads and durable DATA writes.
|
|
use clap::Parser;
|
|
use std::{
|
|
fs::{File, OpenOptions},
|
|
io::{Read, Seek, SeekFrom, Write},
|
|
os::unix::fs::OpenOptionsExt,
|
|
path::PathBuf,
|
|
sync::{Arc, Barrier},
|
|
time::Instant,
|
|
};
|
|
#[repr(align(16384))]
|
|
struct Block([u8; 65536]);
|
|
#[derive(Parser)]
|
|
#[command(about = "Read eleven cartridge fixtures while writing disposable DATA")]
|
|
struct Cli {
|
|
#[arg(required = true, num_args = 11)]
|
|
paths: Vec<PathBuf>,
|
|
}
|
|
fn main() {
|
|
let paths = Cli::parse().paths;
|
|
let barrier = Arc::new(Barrier::new(12));
|
|
let origin = Instant::now();
|
|
let mut jobs = Vec::new();
|
|
for (index, path) in paths.into_iter().enumerate() {
|
|
let barrier = barrier.clone();
|
|
jobs.push(std::thread::spawn(move || {
|
|
let mut file = OpenOptions::new()
|
|
.read(true)
|
|
.custom_flags(libc::O_DIRECT)
|
|
.open(path)
|
|
.unwrap(); // O_DIRECT
|
|
let mut block = Box::new(Block([0; 65536]));
|
|
barrier.wait();
|
|
let start = origin.elapsed().as_nanos();
|
|
for _ in 0..4 {
|
|
file.seek(SeekFrom::Start(0)).unwrap();
|
|
for _ in 0..128 {
|
|
file.read_exact(&mut block.0).unwrap();
|
|
assert!(block.0.iter().all(|b| *b == (index + 2) as u8));
|
|
}
|
|
}
|
|
(
|
|
index + 2,
|
|
start,
|
|
origin.elapsed().as_nanos(),
|
|
32 * 1024 * 1024,
|
|
)
|
|
}));
|
|
}
|
|
let writer = std::thread::spawn(move || {
|
|
let mut file = File::create("/data/stress.bin").unwrap();
|
|
let mut block = [0_u8; 65536];
|
|
for (i, byte) in block.iter_mut().enumerate() {
|
|
*byte = (i % 256) as u8;
|
|
}
|
|
barrier.wait();
|
|
let start = origin.elapsed().as_nanos();
|
|
for _ in 0..1024 {
|
|
file.write_all(&block).unwrap();
|
|
}
|
|
file.sync_all().unwrap();
|
|
(1, start, origin.elapsed().as_nanos(), 64 * 1024 * 1024)
|
|
});
|
|
let mut results: Vec<_> = jobs.into_iter().map(|j| j.join().unwrap()).collect();
|
|
results.push(writer.join().unwrap());
|
|
for (bay, start, end, bytes) in results {
|
|
println!("{{\"bay\":{bay},\"start_ns\":{start},\"end_ns\":{end},\"bytes\":{bytes}}}");
|
|
}
|
|
}
|