DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Line Code
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 85 86
extern crate docopt;
extern crate rayon;
#[macro_use]
extern crate serde_derive;
extern crate serde;

use docopt::Docopt;
use std::io;
use std::process;

const USAGE: &'static str = "
Usage: cpu_monitor [options] <scenario>
       cpu_monitor --help

A test for monitoring how much CPU usage Rayon consumes under various
scenarios. This test is intended to be executed interactively, like so:

    cargo run --example cpu_monitor -- tasks_ended

The list of scenarios you can try are as follows:

- tasks_ended: after all tasks have finished, go to sleep
- task_stall_root: a root task stalls for a very long time
- task_stall_scope: a task in a scope stalls for a very long time

Options:
    -h, --help                   Show this message.
    -d N, --depth N              Control how hard the dummy task works [default: 27]
";

#[derive(Deserialize)]
pub struct Args {
    arg_scenario: String,
    flag_depth: usize,
}

fn main() {
    let args: &Args =
        &Docopt::new(USAGE).and_then(|d| d.deserialize()).unwrap_or_else(|e| e.exit());

    match &args.arg_scenario[..] {
        "tasks_ended" => tasks_ended(args),
        "task_stall_root" => task_stall_root(args),
        "task_stall_scope" => task_stall_scope(args),
        _ => {
            println!("unknown scenario: `{}`", args.arg_scenario);
            println!("try --help");
            process::exit(1);
        }
    }
}

fn wait_for_user() {
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
}

fn task(args: &Args) {
    fn join_recursively(n: usize) {
        if n == 0 {
            return;
        }
        rayon::join(|| join_recursively(n - 1), || join_recursively(n - 1));
    }

    println!("Starting heavy work at depth {}...wait.", args.flag_depth);
    join_recursively(args.flag_depth);
    println!("Heavy work done; check top. You should see CPU usage drop to zero soon.");
    println!("Press <enter> to quit...");
}

fn tasks_ended(args: &Args) {
    task(args);
    wait_for_user();
}

fn task_stall_root(args: &Args) {
    rayon::join(|| task(args), || wait_for_user());
}

fn task_stall_scope(args: &Args) {
    rayon::scope(|scope| {
                     scope.spawn(move |_| task(args));
                     scope.spawn(move |_| wait_for_user());
                 });
}