mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-10 20:19:07 +00:00
sys_util: Add the interface to get CPU affinity
At present we only have a interface to set the CPU affinity and don't implement the 'get_cpu_affinity' interface. With a 'get_cpu_affinity' interface, after the thread iterates through all physical CPUs by setting CPU affinity, it can reset its original CPU affinity that was obtained and stored through 'get_cpu_affinity' in advance. BUG=None TEST=cargo build TEST=./test_all TEST=set the CPU affinity and check the return value of 'get_cpu_affinity' Change-Id: I169fbbbb141ca80c980900ed16e4bceed1ba6432 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3217032 Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Chirantan Ekbote <chirantan@chromium.org> Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
This commit is contained in:
parent
81d454515f
commit
952feb761d
1 changed files with 34 additions and 1 deletions
|
@ -7,7 +7,10 @@
|
|||
use std::iter::FromIterator;
|
||||
use std::mem;
|
||||
|
||||
use libc::{cpu_set_t, prctl, sched_setaffinity, CPU_SET, CPU_SETSIZE, CPU_ZERO, EINVAL};
|
||||
use libc::{
|
||||
cpu_set_t, prctl, sched_getaffinity, sched_setaffinity, CPU_ISSET, CPU_SET, CPU_SETSIZE,
|
||||
CPU_ZERO, EINVAL,
|
||||
};
|
||||
|
||||
use crate::{errno_result, Error, Result};
|
||||
|
||||
|
@ -15,6 +18,26 @@ use crate::{errno_result, Error, Result};
|
|||
// impl doesn't reference any types from inside this crate.
|
||||
struct CpuSet(cpu_set_t);
|
||||
|
||||
impl CpuSet {
|
||||
pub fn new() -> CpuSet {
|
||||
// cpu_set_t is a C struct and can be safely initialized with zeroed memory.
|
||||
let mut cpuset: cpu_set_t = unsafe { mem::MaybeUninit::zeroed().assume_init() };
|
||||
// Safe because we pass a valid cpuset pointer.
|
||||
unsafe { CPU_ZERO(&mut cpuset) };
|
||||
CpuSet(cpuset)
|
||||
}
|
||||
|
||||
pub fn to_cpus(&self) -> Vec<usize> {
|
||||
let mut cpus = Vec::new();
|
||||
for i in 0..(CPU_SETSIZE as usize) {
|
||||
if unsafe { CPU_ISSET(i, &self.0) } {
|
||||
cpus.push(i);
|
||||
}
|
||||
}
|
||||
cpus
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<usize> for CpuSet {
|
||||
fn from_iter<I: IntoIterator<Item = usize>>(cpus: I) -> Self {
|
||||
// cpu_set_t is a C struct and can be safely initialized with zeroed memory.
|
||||
|
@ -63,6 +86,16 @@ pub fn set_cpu_affinity<I: IntoIterator<Item = usize>>(cpus: I) -> Result<()> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_cpu_affinity() -> Result<Vec<usize>> {
|
||||
let mut cpu_set = CpuSet::new();
|
||||
|
||||
// Safe because we pass 0 for the current thread, and cpu_set.0 is a valid pointer and only
|
||||
// used for the duration of this call.
|
||||
crate::syscall!(unsafe { sched_getaffinity(0, mem::size_of_val(&cpu_set.0), &mut cpu_set.0) })?;
|
||||
|
||||
Ok(cpu_set.to_cpus())
|
||||
}
|
||||
|
||||
/// Enable experimental core scheduling for the current thread.
|
||||
///
|
||||
/// If successful, the kernel should not schedule this thread with any other thread within the same
|
||||
|
|
Loading…
Reference in a new issue