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
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
use util::*;

#[derive(Clone, Debug)]
pub struct Cpu {
	id: usize,
	core_id: usize,
	physical_package_id: usize,
	core_siblings: Vec<bool>,
	thread_siblings: Vec<bool>,
	node_id: Option<usize>,
}

impl Cpu {
	pub fn new(id: usize) -> Result<Cpu, &'static str> {
		let cpu = Cpu {
			id: id,
			core_id: 0,
			physical_package_id: 0,
			core_siblings: Vec::new(),
			thread_siblings: Vec::new(),
			node_id: None,
		};
		cpu.init()
	}

	fn init(mut self) -> Result<Self, &'static str> {
		if let Ok(core_id) = get_core_id(self.id) {
			self.core_id = core_id;
		} else {
			return Err("invalid core_id");
		}
		if let Ok(physical_package_id) = get_physical_package_id(self.id) {
			self.physical_package_id = physical_package_id;
		} else {
			return Err("invalid physical_package_id");
		}
		if let Ok(core_siblings) = get_core_siblings(self.id) {
			self.core_siblings = core_siblings;
		} else {
			return Err("invalid core_siblings");
		}
		if let Ok(thread_siblings) = get_thread_siblings(self.id) {
			self.thread_siblings = thread_siblings;
		} else {
			return Err("invalid thread_siblings");
		}
		Ok(self)
	}

	pub fn id(&self) -> usize {
		self.id
	}

	pub fn core_id(&self) -> usize {
		self.core_id
	}

	pub fn set_node_id(&mut self, node_id: usize) {
		self.node_id = Some(node_id);
	}

	pub fn node_id(&self) -> Option<usize> {
		self.node_id
	}

	pub fn physical_package_id(&self) -> usize {
		self.physical_package_id
	}

	pub fn core_siblings(&self) -> Vec<bool> {
		self.core_siblings.clone()
	}

	pub fn thread_siblings(&self) -> Vec<bool> {
		self.thread_siblings.clone()
	}

	pub fn is_core_sibling(&self, id: usize) -> bool {
		self.core_siblings[id]
	}

	pub fn is_thread_sibling(&self, id: usize) -> bool {
		self.thread_siblings[id]
	}
}

fn get_core_id(id: usize) -> Result<usize, &'static str> {
	let path = format!("/sys/devices/system/cpu/cpu{}/topology/core_id", id);
	usize_from_file(path)
}

fn get_core_siblings(id: usize) -> Result<Vec<bool>, &'static str> {
	let path = format!("/sys/devices/system/cpu/cpu{}/topology/core_siblings", id);
	bitmask_from_hex_file(path)
}

fn get_thread_siblings(id: usize) -> Result<Vec<bool>, &'static str> {
	let path = format!("/sys/devices/system/cpu/cpu{}/topology/thread_siblings", id);
	bitmask_from_hex_file(path)
}

fn get_physical_package_id(id: usize) -> Result<usize, &'static str> {
	let path = format!("/sys/devices/system/cpu/cpu{}/topology/physical_package_id", id);
	usize_from_file(path)
}