Initial commit
This is the first working version with proper thread synchronization.master
commit
5b022693b0
|
@ -0,0 +1,2 @@
|
|||
/target/
|
||||
**/*.rs.bk
|
|
@ -0,0 +1,121 @@
|
|||
[root]
|
||||
name = "iostress"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap 2.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.26.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"textwrap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "term_size"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-build"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
|
||||
"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
|
||||
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
||||
"checksum clap 2.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2267a8fdd4dce6956ba6649e130f62fb279026e5e84b92aa939ac8f85ce3f9f0"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "8a014d9226c2cc402676fbe9ea2e15dd5222cd1dd57f576b5b283178c944a264"
|
||||
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
|
||||
"checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209"
|
||||
"checksum textwrap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f728584ea33b0ad19318e20557cb0a39097751dbb07171419673502f848c7af6"
|
||||
"checksum unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8083c594e02b8ae1654ae26f0ade5158b119bd88ad0e8227a5d8fcd72407946"
|
||||
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
|
||||
"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
|
@ -0,0 +1,7 @@
|
|||
[package]
|
||||
name = "iostress"
|
||||
version = "0.1.0"
|
||||
authors = ["Dustin C. Hatch <dustin.hatch@firemon.com>"]
|
||||
|
||||
[dependencies]
|
||||
clap = "2.26"
|
|
@ -0,0 +1,126 @@
|
|||
extern crate clap;
|
||||
|
||||
use std::process;
|
||||
use std::sync;
|
||||
use std::thread;
|
||||
|
||||
|
||||
struct Args {
|
||||
num_threads: usize,
|
||||
}
|
||||
|
||||
|
||||
struct IOStressContext {
|
||||
data: sync::RwLock<Vec<u8>>,
|
||||
barrier: sync::Barrier,
|
||||
lock: sync::Mutex<usize>,
|
||||
cond: sync::Condvar,
|
||||
}
|
||||
|
||||
|
||||
impl IOStressContext {
|
||||
fn new(t: usize) -> IOStressContext {
|
||||
IOStressContext {
|
||||
data: sync::RwLock::new(Vec::with_capacity(4096)),
|
||||
barrier: sync::Barrier::new(t + 1),
|
||||
lock: sync::Mutex::new(0),
|
||||
cond: sync::Condvar::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn parse_args() -> Args {
|
||||
let app = clap::App::new("iostress")
|
||||
.version("0.1")
|
||||
.author("Dustin C. Hatch <dustin.hatch@firemon.com>")
|
||||
.about("I/O stress test tool")
|
||||
.arg(clap::Arg::with_name("threads")
|
||||
.short("t")
|
||||
.long("threads")
|
||||
.value_name("COUNT")
|
||||
.default_value("1")
|
||||
.help("Number of simultaneous tests")
|
||||
.takes_value(true));
|
||||
let matches = app.get_matches();
|
||||
|
||||
Args {
|
||||
num_threads: match matches.value_of("threads").unwrap().parse() {
|
||||
Ok(n) => n,
|
||||
Err(_) => {
|
||||
eprintln!("Invalid thread count");
|
||||
process::exit(2);
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn worker_thread(ctx: sync::Arc<IOStressContext>) {
|
||||
let thread = thread::current();
|
||||
let name = thread.name().unwrap();
|
||||
let mut prev_ctr: usize = 0;
|
||||
loop {
|
||||
{
|
||||
let mut ctr = ctx.lock.lock().unwrap();
|
||||
while *ctr <= prev_ctr {
|
||||
println!("{} waiting on condition", name);
|
||||
ctr = ctx.cond.wait(ctr).unwrap();
|
||||
}
|
||||
println!("{} woke up, counter: {} -> {}", name, prev_ctr, *ctr);
|
||||
prev_ctr = *ctr;
|
||||
}
|
||||
{
|
||||
let data = ctx.data.read().unwrap();
|
||||
// Here is where the actual processing would occur
|
||||
println!("{} data: {:?}", name, *data);
|
||||
if (*data).len() == 0 {
|
||||
println!("{} done!", name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
println!("{} waiting at barrier", name);
|
||||
ctx.barrier.wait();
|
||||
}
|
||||
println!("{} waiting at final barrier", name);
|
||||
ctx.barrier.wait();
|
||||
println!("{} terminating", name);
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let args = parse_args();
|
||||
|
||||
let ctx = sync::Arc::new(IOStressContext::new(args.num_threads));
|
||||
let mut threads = Vec::with_capacity(args.num_threads);
|
||||
for i in 0..args.num_threads {
|
||||
let c = ctx.clone();
|
||||
let t = thread::Builder::new().name(format!("thread{}", i + 1));
|
||||
threads.push(t.spawn(move || worker_thread(c)).unwrap());
|
||||
}
|
||||
|
||||
for i in 0..5 {
|
||||
{
|
||||
let mut data = ctx.data.write().unwrap();
|
||||
if i == 4 {
|
||||
(*data).clear();
|
||||
} else {
|
||||
// Here is where data would be fetched and sent to the workers
|
||||
(*data).push(i + 1);
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut ctr = ctx.lock.lock().unwrap();
|
||||
*ctr += 1;
|
||||
println!("Notifying threads");
|
||||
ctx.cond.notify_all();
|
||||
}
|
||||
println!("Waiting for threads to finish iteration {}", i + 1);
|
||||
ctx.barrier.wait();
|
||||
}
|
||||
|
||||
for thread in threads {
|
||||
println!("waiting for {}", thread.thread().name().unwrap());
|
||||
thread.join().unwrap();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue