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
106
107
108
109
110
#[derive(Default, Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
#[derive(Deserialize, Serialize)]
pub struct InterruptRequest(u16);
impl From<u16> for InterruptRequest
{
#[inline(always)]
fn from(value: u16) -> Self
{
InterruptRequest(value)
}
}
impl Into<u16> for InterruptRequest
{
#[inline(always)]
fn into(self) -> u16
{
self.0
}
}
impl InterruptRequest
{
#[inline(always)]
#[cfg(any(target_os = "android", target_os = "linux"))]
pub fn read_interrupt_request_to_hyper_threads_affinity(&self, proc_path: &ProcPath) -> Result<BTreeSet<HyperThread>, ListParseError>
{
proc_path.file_path(&format!("irq/{}/smp_affinity_list", self.0)).read_linux_core_or_numa_list(HyperThread::from)
}
#[inline(always)]
#[cfg(any(target_os = "android", target_os = "linux"))]
pub fn read_interrupt_request_to_hyper_threads_affinity_hint(&self, proc_path: &ProcPath) -> Result<BTreeSet<HyperThread>, ListParseError>
{
proc_path.file_path(&format!("irq/{}/affinity_hint", self.0)).read_linux_core_or_numa_list(HyperThread::from)
}
#[inline(always)]
#[cfg(any(target_os = "android", target_os = "linux"))]
pub fn read_interrupt_request_node(&self, proc_path: &ProcPath) -> Result<u8, io::Error>
{
proc_path.file_path(&format!("irq/{}/node", self.0)).read_value()
}
#[inline(always)]
#[cfg(any(target_os = "android", target_os = "linux"))]
pub fn read_default_interrupt_request_affinity_hyper_thread_bitmask(proc_path: &ProcPath) -> Result<HyperThreadBitmask, io::Error>
{
proc_path.file_path("irq/default_smp_affinity").parse_linux_core_or_numa_bitmask()
}
#[inline(always)]
#[cfg(any(target_os = "android", target_os = "linux"))]
pub fn force_all_interrupt_requests_to_just_these_hyper_threads(hyper_threads: &BTreeSet<HyperThread>, proc_path: &ProcPath) -> io::Result<()>
{
let mask = HyperThread::hyper_threads_to_mask(hyper_threads);
proc_path.file_path("irq/default_smp_affinity").write_value(&mask)?;
if let Ok(interrupt_requests) = InterruptRequest::interrupt_requests(proc_path)
{
for interrupt_request in interrupt_requests.iter()
{
proc_path.file_path(&format!("irq/{}/smp_affinity", interrupt_request.0)).write_value(&mask)?;
proc_path.file_path(&format!("irq/{}/affinity_hint", interrupt_request.0)).write_value(&mask)?;
}
}
Ok(())
}
#[inline(always)]
#[cfg(any(target_os = "android", target_os = "linux"))]
pub fn interrupt_requests(proc_path: &ProcPath) -> Result<BTreeSet<Self>, io::Error>
{
let mut interrupt_requests = BTreeSet::new();
let irq_folder_path = proc_path.file_path("irq");
for entry in irq_folder_path.read_dir()?
{
let entry = entry?;
if entry.file_type()?.is_file()
{
if let Some(string) = entry.file_name().as_os_str().to_str()
{
if let Ok(interrupt_request) = string.parse::<u16>()
{
interrupt_requests.insert(InterruptRequest(interrupt_request));
}
}
}
}
Ok(interrupt_requests)
}
}