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
use runnable::Runnable;
use std::process::exit;
use std::sync::{Arc, Mutex};
use runlist::RunList;
fn init(runnables: Vec<Arc<Mutex<Runnable>>>) -> RunList {
let mut run_list = RunList::new();
info!("Initializing runnables");
for runnable_arc in &runnables {
let mut runnable = runnable_arc.lock().unwrap();
info!("Initializing runnable #{}", &runnable.id());
if runnable.init() {
debug!("Runnable #{} inputs ready, added to run list", &runnable.id());
run_list.inputs_ready(runnable.id());
}
}
run_list.set_runnables(runnables);
run_list
}
pub fn execute(runnables: Vec<Arc<Mutex<Runnable>>>) -> ! {
let mut run_list = init(runnables);
info!("Starting execution loop");
while let Some(runnable_arc) = run_list.next() {
let mut runnable = runnable_arc.lock().unwrap();
info!("Running runnable #{}", runnable.id());
let output = runnable.run();
run_list.unblock_by(runnable.id());
for (destination_id, io_number) in runnable.output_destinations() {
let destination_arc = run_list.get(destination_id);
let mut destination = destination_arc.lock().unwrap();
info!("Sending output '{:?}' to ({}, {})", &output, &destination_id, &io_number);
run_list.blocked_by(destination_id, runnable.id());
destination.write_input(io_number, output.clone());
if destination.inputs_satisfied() {
run_list.inputs_ready(destination_id);
}
}
}
exit(0);
}