Skip to content

Commit 3a56d16

Browse files
committed
Add cgroups support for Linux targets
1 parent bfce940 commit 3a56d16

File tree

10 files changed

+446
-73
lines changed

10 files changed

+446
-73
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
100000
2+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
150000
2+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
100000
2+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
600000
2+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
0
2+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
600000

fixtures/cgroups/proc/cgroups/cgroup

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
12:perf_event:/
2+
11:cpu,cpuacct:/
3+
3:devices:/user.slice
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
1 0 8:1 / / rw,noatime shared:1 - ext4 /dev/sda1 rw,errors=remount-ro,data=reordered
2+
2 1 0:1 / /dev rw,relatime shared:2 - devtmpfs udev rw,size=10240k,nr_inodes=16487629,mode=755
3+
3 1 0:2 / /proc rw,nosuid,nodev,noexec,relatime shared:3 - proc proc rw
4+
4 1 0:3 / /sys rw,nosuid,nodev,noexec,relatime shared:4 - sysfs sysfs rw
5+
5 4 0:4 / /sys/fs/cgroup ro,nosuid,nodev,noexec shared:5 - tmpfs tmpfs ro,mode=755
6+
6 5 0:5 / /sys/fs/cgroup/cpuset rw,nosuid,nodev,noexec,relatime shared:6 - cgroup cgroup rw,cpuset
7+
7 5 0:6 / /sys/fs/cgroup/cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:7 - cgroup cgroup rw,cpu,cpuacct
8+
8 5 0:7 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime shared:8 - cgroup cgroup rw,memory

src/lib.rs

Lines changed: 10 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ extern crate libc;
3737
#[cfg(target_os = "hermit")]
3838
extern crate hermit_abi;
3939

40+
#[cfg(target_os = "linux")]
41+
mod linux;
42+
#[cfg(target_os = "linux")]
43+
use linux::{get_num_cpus, get_num_physical_cpus};
44+
4045
/// Returns the number of available CPUs of the current system.
4146
///
4247
/// This function will get the number of logical cores. Sometimes this is different from the number
@@ -55,11 +60,14 @@ extern crate hermit_abi;
5560
///
5661
/// # Note
5762
///
58-
/// This will check [sched affinity] on Linux, showing a lower number of CPUs if the current
59-
/// thread does not have access to all the computer's CPUs.
63+
/// This will check [sched affinity] on Linux, showing a lower number of CPUs if the current
64+
/// thread does not have access to all the computer's CPUs.
65+
///
66+
/// This will also check [cgroups], frequently used in containers to constrain CPU usage.
6067
///
6168
/// [smt]: https://en.wikipedia.org/wiki/Simultaneous_multithreading
6269
/// [sched affinity]: http://www.gnu.org/software/libc/manual/html_node/CPU-Affinity.html
70+
/// [cgroups]: https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt
6371
#[inline]
6472
pub fn get() -> usize {
6573
get_num_cpus()
@@ -189,56 +197,6 @@ fn get_num_physical_cpus_windows() -> Option<usize> {
189197
}
190198
}
191199

192-
#[cfg(target_os = "linux")]
193-
fn get_num_physical_cpus() -> usize {
194-
use std::collections::HashMap;
195-
use std::fs::File;
196-
use std::io::BufRead;
197-
use std::io::BufReader;
198-
199-
let file = match File::open("/proc/cpuinfo") {
200-
Ok(val) => val,
201-
Err(_) => return get_num_cpus(),
202-
};
203-
let reader = BufReader::new(file);
204-
let mut map = HashMap::new();
205-
let mut physid: u32 = 0;
206-
let mut cores: usize = 0;
207-
let mut chgcount = 0;
208-
for line in reader.lines().filter_map(|result| result.ok()) {
209-
let mut it = line.split(':');
210-
let (key, value) = match (it.next(), it.next()) {
211-
(Some(key), Some(value)) => (key.trim(), value.trim()),
212-
_ => continue,
213-
};
214-
if key == "physical id" {
215-
match value.parse() {
216-
Ok(val) => physid = val,
217-
Err(_) => break,
218-
};
219-
chgcount += 1;
220-
}
221-
if key == "cpu cores" {
222-
match value.parse() {
223-
Ok(val) => cores = val,
224-
Err(_) => break,
225-
};
226-
chgcount += 1;
227-
}
228-
if chgcount == 2 {
229-
map.insert(physid, cores);
230-
chgcount = 0;
231-
}
232-
}
233-
let count = map.into_iter().fold(0, |acc, (_, cores)| acc + cores);
234-
235-
if count == 0 {
236-
get_num_cpus()
237-
} else {
238-
count
239-
}
240-
}
241-
242200
#[cfg(windows)]
243201
fn get_num_cpus() -> usize {
244202
#[repr(C)]
@@ -366,27 +324,6 @@ fn get_num_physical_cpus() -> usize {
366324
cpus as usize
367325
}
368326

369-
#[cfg(target_os = "linux")]
370-
fn get_num_cpus() -> usize {
371-
let mut set: libc::cpu_set_t = unsafe { std::mem::zeroed() };
372-
if unsafe { libc::sched_getaffinity(0, std::mem::size_of::<libc::cpu_set_t>(), &mut set) } == 0 {
373-
let mut count: u32 = 0;
374-
for i in 0..libc::CPU_SETSIZE as usize {
375-
if unsafe { libc::CPU_ISSET(i, &set) } {
376-
count += 1
377-
}
378-
}
379-
count as usize
380-
} else {
381-
let cpus = unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) };
382-
if cpus < 1 {
383-
1
384-
} else {
385-
cpus as usize
386-
}
387-
}
388-
}
389-
390327
#[cfg(any(
391328
target_os = "nacl",
392329
target_os = "macos",

0 commit comments

Comments
 (0)