75fa9f6dec
This commit is extracted from #122036 and adds a new directive to the `compiletest` test runner, `//@ needs-threads`. This is intended to capture the need that a target must implement threading to execute a specific test, typically one that uses `std::thread`. This is primarily done for WebAssembly targets which currently do not have threads by default. This enables transitioning a lot of `//@ ignore-wasm*`-style ignores into a more self-documenting `//@ needs-threads` directive. Additionally the `wasm32-wasi-preview1-threads` target, for example, does actually have threads, but isn't tested in CI at this time. This change enables running these tests for that target, but not other wasm targets.
96 lines
2.7 KiB
Rust
96 lines
2.7 KiB
Rust
//@ run-pass
|
|
|
|
#![allow(improper_ctypes_definitions)]
|
|
#![allow(non_camel_case_types)]
|
|
#![allow(dead_code)]
|
|
#![allow(unused_mut)]
|
|
//@ needs-threads
|
|
|
|
/**
|
|
A somewhat reduced test case to expose some Valgrind issues.
|
|
|
|
This originally came from the word-count benchmark.
|
|
*/
|
|
|
|
pub fn map(filename: String, mut emit: map_reduce::putter) {
|
|
emit(filename, "1".to_string());
|
|
}
|
|
|
|
mod map_reduce {
|
|
use std::collections::HashMap;
|
|
use std::sync::mpsc::{channel, Sender};
|
|
use std::str;
|
|
use std::thread;
|
|
|
|
pub type putter<'a> = Box<dyn FnMut(String, String) + 'a>;
|
|
|
|
pub type mapper = extern "C" fn(String, putter);
|
|
|
|
enum ctrl_proto { find_reducer(Vec<u8>, Sender<isize>), mapper_done, }
|
|
|
|
fn start_mappers(ctrl: Sender<ctrl_proto>, inputs: Vec<String>) {
|
|
for i in &inputs {
|
|
let ctrl = ctrl.clone();
|
|
let i = i.clone();
|
|
thread::spawn(move|| map_task(ctrl.clone(), i.clone()) );
|
|
}
|
|
}
|
|
|
|
fn map_task(ctrl: Sender<ctrl_proto>, input: String) {
|
|
let mut intermediates = HashMap::new();
|
|
|
|
fn emit(im: &mut HashMap<String, isize>,
|
|
ctrl: Sender<ctrl_proto>, key: String,
|
|
_val: String) {
|
|
if im.contains_key(&key) {
|
|
return;
|
|
}
|
|
let (tx, rx) = channel();
|
|
println!("sending find_reducer");
|
|
ctrl.send(ctrl_proto::find_reducer(key.as_bytes().to_vec(), tx)).unwrap();
|
|
println!("receiving");
|
|
let c = rx.recv().unwrap();
|
|
println!("{}", c);
|
|
im.insert(key, c);
|
|
}
|
|
|
|
let ctrl_clone = ctrl.clone();
|
|
::map(input, Box::new(|a,b| emit(&mut intermediates, ctrl.clone(), a, b)));
|
|
ctrl_clone.send(ctrl_proto::mapper_done).unwrap();
|
|
}
|
|
|
|
pub fn map_reduce(inputs: Vec<String>) {
|
|
let (tx, rx) = channel();
|
|
|
|
// This thread becomes the master control thread. It spawns others
|
|
// to do the rest.
|
|
|
|
let mut reducers: HashMap<String, isize>;
|
|
|
|
reducers = HashMap::new();
|
|
|
|
start_mappers(tx, inputs.clone());
|
|
|
|
let mut num_mappers = inputs.len() as isize;
|
|
|
|
while num_mappers > 0 {
|
|
match rx.recv().unwrap() {
|
|
ctrl_proto::mapper_done => { num_mappers -= 1; }
|
|
ctrl_proto::find_reducer(k, cc) => {
|
|
let mut c;
|
|
match reducers.get(&str::from_utf8(&k).unwrap().to_string()) {
|
|
Some(&_c) => { c = _c; }
|
|
None => { c = 0; }
|
|
}
|
|
cc.send(c).unwrap();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn main() {
|
|
map_reduce::map_reduce(
|
|
vec!["../tests/run-pass/hashmap-memory.rs".to_string()]);
|
|
}
|