1use std::io::prelude::*;
2use std::fs::File;
3
4use cpu::Cpu;
5use util;
6
7#[derive(Clone, Debug)]
8pub struct Node {
9 id: usize,
10 cpus: Vec<Cpu>,
11 cpumask: Vec<bool>,
12 mem_free: u64,
13 mem_total: u64,
14 mem_used: u64,
15 hugepages_2m_free: usize,
16 hugepages_2m_total: usize,
17 hugepages_1g_free: usize,
18 hugepages_1g_total: usize,
19}
20
21impl Node {
22 pub fn new(id: usize) -> Result<Node, &'static str> {
23 let node = Node {
24 id: id,
25 cpus: Vec::new(),
26 cpumask: Vec::new(),
27 mem_free: 0, mem_total: 0, mem_used: 0, hugepages_1g_total: 0,
31 hugepages_1g_free: 0,
32 hugepages_2m_total: 0,
33 hugepages_2m_free: 0,
34 };
35 node.init()
36 }
37
38 fn init(mut self) -> Result<Self, &'static str> {
39 if let Ok(cpumask) = util::bitmask_from_hex_file(format!("/sys/devices/system/node/node{}/cpumap",
40 self.id)) {
41 self.cpumask = cpumask.clone();
42 for i in 0..4096 {
43 if let Ok(mut cpu) = Cpu::new(self.id, i) {
44 cpu.set_node_id(self.id);
45 self.cpus.push(cpu);
46 }
47 }
48 self.mem_init();
49 Ok(self)
50 } else {
51 Err("no node found")
52 }
53 }
54
55 fn mem_init(&mut self) {
56 let path = format!("/sys/devices/system/node/node{}/meminfo", self.id);
57 if let Ok(mut f) = File::open(&path) {
58 let mut s = String::new();
59 if let Ok(_) = f.read_to_string(&mut s) {
60 for l in s.lines() {
61 let tokens: Vec<&str> = l.split_whitespace().collect();
62 match tokens[2] {
63 "MemTotal:" => {
64 self.mem_total = tokens[3].parse().unwrap_or(0);
65 }
66 "MemUsed:" => {
67 self.mem_used = tokens[3].parse().unwrap_or(0);
68 }
69 "MemFree:" => {
70 self.mem_free = tokens[3].parse().unwrap_or(0);
71 }
72 _ => {}
73 }
74 }
75 }
76 }
77 self.hugepages_2m_free = util::usize_from_file(format!("/sys/devices/system/node/node{}/hugepages/hugepages-2048kB/free_hugepages", self.id)).unwrap_or(0);
78 self.hugepages_2m_total = util::usize_from_file(format!("/sys/devices/system/node/node{}/hugepages/hugepages-2048kB/nr_hugepages", self.id)).unwrap_or(0);
79 self.hugepages_1g_free = util::usize_from_file(format!("/sys/devices/system/node/node{}/hugepages/hugepages-1048576kB/free_hugepages", self.id)).unwrap_or(0);
80 self.hugepages_1g_total = util::usize_from_file(format!("/sys/devices/system/node/node{}/hugepages/hugepages-1048576kB/nr_hugepages", self.id)).unwrap_or(0);
81 }
82
83 pub fn id(&self) -> usize {
84 self.id
85 }
86
87 pub fn cpus(&self) -> &Vec<Cpu> {
88 &self.cpus
89 }
90
91 pub fn cpumask(&self) -> &Vec<bool> {
92 &self.cpumask
93 }
94
95 pub fn mem_free(&self) -> u64 {
96 self.mem_free
97 }
98
99 pub fn mem_total(&self) -> u64 {
100 self.mem_total
101 }
102
103 pub fn mem_used(&self) -> u64 {
104 self.mem_used
105 }
106
107 pub fn hugepages_2m_free(&self) -> usize {
108 self.hugepages_2m_free
109 }
110
111 pub fn hugepages_2m_total(&self) -> usize {
112 self.hugepages_2m_total
113 }
114
115 pub fn hugepages_1g_free(&self) -> usize {
116 self.hugepages_1g_free
117 }
118
119 pub fn hugepages_1g_total(&self) -> usize {
120 self.hugepages_1g_total
121 }
122}