1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
//@ run-pass
//@ ignore-wasm32 no processes
//@ ignore-sgx no processes
use std::env;
use std::io::prelude::*;
use std::process::Command;
use std::thread;
const THREADS: usize = 20;
const WRITES: usize = 100;
const WRITE_SIZE: usize = 1024 * 32;
fn main() {
let args = env::args().collect::<Vec<_>>();
if args.len() == 1 {
parent();
} else {
child();
}
}
fn parent() {
let me = env::current_exe().unwrap();
let mut cmd = Command::new(me);
cmd.arg("run-the-test");
let output = cmd.output().unwrap();
assert!(output.status.success());
assert_eq!(output.stderr.len(), 0);
assert_eq!(output.stdout.len(), WRITES * THREADS * WRITE_SIZE);
for byte in output.stdout.iter() {
assert_eq!(*byte, b'a');
}
}
fn child() {
let threads = (0..THREADS).map(|_| {
thread::spawn(|| {
let buf = [b'a'; WRITE_SIZE];
for _ in 0..WRITES {
write_all(&buf);
}
})
}).collect::<Vec<_>>();
for thread in threads {
thread.join().unwrap();
}
}
#[cfg(unix)]
fn write_all(buf: &[u8]) {
use std::fs::File;
use std::mem;
use std::os::unix::prelude::*;
let mut file = unsafe { File::from_raw_fd(1) };
let res = file.write_all(buf);
mem::forget(file);
res.unwrap();
}
#[cfg(windows)]
fn write_all(buf: &[u8]) {
use std::fs::File;
use std::mem;
use std::os::windows::raw::*;
use std::os::windows::prelude::*;
const STD_OUTPUT_HANDLE: u32 = (-11i32) as u32;
extern "system" {
fn GetStdHandle(handle: u32) -> HANDLE;
}
let mut file = unsafe {
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
assert!(!handle.is_null());
File::from_raw_handle(handle)
};
let res = file.write_all(buf);
mem::forget(file);
res.unwrap();
}
|