diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-07-03 04:34:43 +0000 |
---|---|---|
committer | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-07-03 04:34:43 +0000 |
commit | 112438b1e954c1266a76f8c53fd084f9019ebc99 (patch) | |
tree | 1ea0471db8799b17c07e219638f32b8371cb0514 | |
parent | dc5f8eeb685b04bd2f78319abac6677917c1bd46 (diff) | |
parent | b9a21abb51af1823c2510268d19a5a8ca40d9bdf (diff) | |
download | nix-112438b1e954c1266a76f8c53fd084f9019ebc99.zip |
Merge #1090
1090: Expose sched_yield on non-linux-like hosts r=asomers a=kubkon
Currently, `sched` module is compiled only for linux-like hosts. However, the recently added syscall `sched_yield` is universal to all *nixes. This PR pulls all linux-like functionality into a private `sched_linux_like` module which is enabled only for android and linux hosts, while `sched_yield` and `sched` modules are now compiled for all *nixes, thus, correctly exposing `sched_yield` to other non-linux hosts.
Co-authored-by: Jakub Konka <jakub.konka@golem.network>
-rw-r--r-- | CHANGELOG.md | 3 | ||||
-rw-r--r-- | src/lib.rs | 2 | ||||
-rw-r--r-- | src/sched.rs | 230 |
3 files changed, 126 insertions, 109 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index eb440cab..b3d7089e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). ([#928](https://github.com/nix-rust/nix/pull/928)) ### Fixed +- Enabled `sched_yield` for all nix hosts. + ([#1090](https://github.com/nix-rust/nix/pull/1090)) + ### Removed ## [0.14.1] - 2019-06-06 @@ -62,8 +62,6 @@ pub mod net; pub mod poll; #[deny(missing_docs)] pub mod pty; -#[cfg(any(target_os = "android", - target_os = "linux"))] pub mod sched; pub mod sys; // This can be implemented for other platforms as soon as libc diff --git a/src/sched.rs b/src/sched.rs index c4e6ca7a..064fc29d 100644 --- a/src/sched.rs +++ b/src/sched.rs @@ -1,131 +1,147 @@ -use std::mem; -use std::os::unix::io::RawFd; -use std::option::Option; -use libc::{self, c_int, c_void}; -use {Error, Result}; -use errno::Errno; -use ::unistd::Pid; - -// For some functions taking with a parameter of type CloneFlags, -// only a subset of these flags have an effect. -libc_bitflags!{ - pub struct CloneFlags: c_int { - CLONE_VM; - CLONE_FS; - CLONE_FILES; - CLONE_SIGHAND; - CLONE_PTRACE; - CLONE_VFORK; - CLONE_PARENT; - CLONE_THREAD; - CLONE_NEWNS; - CLONE_SYSVSEM; - CLONE_SETTLS; - CLONE_PARENT_SETTID; - CLONE_CHILD_CLEARTID; - CLONE_DETACHED; - CLONE_UNTRACED; - CLONE_CHILD_SETTID; - CLONE_NEWCGROUP; - CLONE_NEWUTS; - CLONE_NEWIPC; - CLONE_NEWUSER; - CLONE_NEWPID; - CLONE_NEWNET; - CLONE_IO; +use libc; +use {Errno, Result}; + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use self::sched_linux_like::*; + +#[cfg(any(target_os = "android", target_os = "linux"))] +mod sched_linux_like { + use errno::Errno; + use libc::{self, c_int, c_void}; + use std::mem; + use std::option::Option; + use std::os::unix::io::RawFd; + use unistd::Pid; + use {Error, Result}; + + // For some functions taking with a parameter of type CloneFlags, + // only a subset of these flags have an effect. + libc_bitflags! { + pub struct CloneFlags: c_int { + CLONE_VM; + CLONE_FS; + CLONE_FILES; + CLONE_SIGHAND; + CLONE_PTRACE; + CLONE_VFORK; + CLONE_PARENT; + CLONE_THREAD; + CLONE_NEWNS; + CLONE_SYSVSEM; + CLONE_SETTLS; + CLONE_PARENT_SETTID; + CLONE_CHILD_CLEARTID; + CLONE_DETACHED; + CLONE_UNTRACED; + CLONE_CHILD_SETTID; + CLONE_NEWCGROUP; + CLONE_NEWUTS; + CLONE_NEWIPC; + CLONE_NEWUSER; + CLONE_NEWPID; + CLONE_NEWNET; + CLONE_IO; + } } -} -pub type CloneCb<'a> = Box<FnMut() -> isize + 'a>; - -#[repr(C)] -#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] -pub struct CpuSet { - cpu_set: libc::cpu_set_t, -} + pub type CloneCb<'a> = Box<FnMut() -> isize + 'a>; -impl CpuSet { - pub fn new() -> CpuSet { - CpuSet { cpu_set: unsafe { mem::zeroed() } } + #[repr(C)] + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct CpuSet { + cpu_set: libc::cpu_set_t, } - pub fn is_set(&self, field: usize) -> Result<bool> { - if field >= 8 * mem::size_of::<libc::cpu_set_t>() { - Err(Error::Sys(Errno::EINVAL)) - } else { - Ok(unsafe { libc::CPU_ISSET(field, &self.cpu_set) }) + impl CpuSet { + pub fn new() -> CpuSet { + CpuSet { + cpu_set: unsafe { mem::zeroed() }, + } } - } - pub fn set(&mut self, field: usize) -> Result<()> { - if field >= 8 * mem::size_of::<libc::cpu_set_t>() { - Err(Error::Sys(Errno::EINVAL)) - } else { - Ok(unsafe { libc::CPU_SET(field, &mut self.cpu_set) }) + pub fn is_set(&self, field: usize) -> Result<bool> { + if field >= 8 * mem::size_of::<libc::cpu_set_t>() { + Err(Error::Sys(Errno::EINVAL)) + } else { + Ok(unsafe { libc::CPU_ISSET(field, &self.cpu_set) }) + } } - } - pub fn unset(&mut self, field: usize) -> Result<()> { - if field >= 8 * mem::size_of::<libc::cpu_set_t>() { - Err(Error::Sys(Errno::EINVAL)) - } else { - Ok(unsafe { libc::CPU_CLR(field, &mut self.cpu_set) }) + pub fn set(&mut self, field: usize) -> Result<()> { + if field >= 8 * mem::size_of::<libc::cpu_set_t>() { + Err(Error::Sys(Errno::EINVAL)) + } else { + Ok(unsafe { libc::CPU_SET(field, &mut self.cpu_set) }) + } } - } -} -pub fn sched_setaffinity(pid: Pid, cpuset: &CpuSet) -> Result<()> { - let res = unsafe { - libc::sched_setaffinity(pid.into(), - mem::size_of::<CpuSet>() as libc::size_t, - &cpuset.cpu_set) - }; + pub fn unset(&mut self, field: usize) -> Result<()> { + if field >= 8 * mem::size_of::<libc::cpu_set_t>() { + Err(Error::Sys(Errno::EINVAL)) + } else { + Ok(unsafe { libc::CPU_CLR(field, &mut self.cpu_set) }) + } + } + } - Errno::result(res).map(drop) -} + pub fn sched_setaffinity(pid: Pid, cpuset: &CpuSet) -> Result<()> { + let res = unsafe { + libc::sched_setaffinity( + pid.into(), + mem::size_of::<CpuSet>() as libc::size_t, + &cpuset.cpu_set, + ) + }; -/// Explicitly yield the processor to other threads. -/// -/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_yield.html) -pub fn sched_yield() -> Result<()> { - let res = unsafe { - libc::sched_yield() - }; + Errno::result(res).map(drop) + } - Errno::result(res).map(drop) -} + pub fn clone( + mut cb: CloneCb, + stack: &mut [u8], + flags: CloneFlags, + signal: Option<c_int>, + ) -> Result<Pid> { + extern "C" fn callback(data: *mut CloneCb) -> c_int { + let cb: &mut CloneCb = unsafe { &mut *data }; + (*cb)() as c_int + } -pub fn clone(mut cb: CloneCb, - stack: &mut [u8], - flags: CloneFlags, - signal: Option<c_int>) - -> Result<Pid> { - extern "C" fn callback(data: *mut CloneCb) -> c_int { - let cb: &mut CloneCb = unsafe { &mut *data }; - (*cb)() as c_int + let res = unsafe { + let combined = flags.bits() | signal.unwrap_or(0); + let ptr = stack.as_mut_ptr().offset(stack.len() as isize); + let ptr_aligned = ptr.offset((ptr as usize % 16) as isize * -1); + libc::clone( + mem::transmute( + callback as extern "C" fn(*mut Box<::std::ops::FnMut() -> isize>) -> i32, + ), + ptr_aligned as *mut c_void, + combined, + &mut cb as *mut _ as *mut c_void, + ) + }; + + Errno::result(res).map(Pid::from_raw) } - let res = unsafe { - let combined = flags.bits() | signal.unwrap_or(0); - let ptr = stack.as_mut_ptr().offset(stack.len() as isize); - let ptr_aligned = ptr.offset((ptr as usize % 16) as isize * -1); - libc::clone(mem::transmute(callback as extern "C" fn(*mut Box<::std::ops::FnMut() -> isize>) -> i32), - ptr_aligned as *mut c_void, - combined, - &mut cb as *mut _ as *mut c_void) - }; - - Errno::result(res).map(Pid::from_raw) -} + pub fn unshare(flags: CloneFlags) -> Result<()> { + let res = unsafe { libc::unshare(flags.bits()) }; + + Errno::result(res).map(drop) + } -pub fn unshare(flags: CloneFlags) -> Result<()> { - let res = unsafe { libc::unshare(flags.bits()) }; + pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> { + let res = unsafe { libc::setns(fd, nstype.bits()) }; - Errno::result(res).map(drop) + Errno::result(res).map(drop) + } } -pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> { - let res = unsafe { libc::setns(fd, nstype.bits()) }; +/// Explicitly yield the processor to other threads. +/// +/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_yield.html) +pub fn sched_yield() -> Result<()> { + let res = unsafe { libc::sched_yield() }; Errno::result(res).map(drop) } |