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
87
88
89
90
91
92
extern crate libc;
use std::ffi::CString;
use std::path::Path;
mod raw;
pub struct Circuit {
pub cores: usize,
pub nodes: usize,
pub capacitance: Vec<f64>,
pub conductance: Vec<f64>,
}
impl Circuit {
pub fn new(floorplan: &Path, config: &Path, params: &str) -> Result<Circuit, &'static str> {
use std::iter::repeat;
use std::ptr::copy_nonoverlapping as copy;
macro_rules! str_to_c_str(
($str:expr) => (
match CString::new($str) {
Ok(result) => result,
Err(_) => return Err("failed to process the arguments"),
}
);
);
macro_rules! path_to_c_str(
($path:expr) => (
match $path.to_str() {
Some(path) => str_to_c_str!(path),
None => return Err("failed to process the arguments"),
}
);
);
unsafe {
let floorplan = path_to_c_str!(floorplan);
let config = path_to_c_str!(config);
let params = str_to_c_str!(params);
let raw_circuit = raw::new_circuit(floorplan.as_ptr(),
config.as_ptr(),
params.as_ptr());
if raw_circuit.is_null() {
return Err("failed to construct a thermal circuit");
}
let nc = (*raw_circuit).nodes as usize;
let mut circuit = Circuit {
cores: (*raw_circuit).cores as usize,
nodes: nc,
capacitance: repeat(0.0).take(nc).collect::<Vec<_>>(),
conductance: repeat(0.0).take(nc * nc).collect::<Vec<_>>(),
};
copy((*raw_circuit).capacitance as *const _,
circuit.capacitance.as_mut_ptr(), nc);
copy((*raw_circuit).conductance as *const _,
circuit.conductance.as_mut_ptr(), nc * nc);
raw::free_circuit(raw_circuit);
Ok(circuit)
}
}
}