From e6b237e1624e17a7fd24d6e6427839d660509b37 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 25 Jun 2019 09:58:43 +0200 Subject: [PATCH 1/3] Move cross compilation cfg for sched into sched mod --- src/lib.rs | 2 - src/sched.rs | 231 +++++++++++++++++++++++++++------------------------ 2 files changed, 122 insertions(+), 111 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b46489331e..22577cfe63 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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 c4e6ca7a1a..ec4d0618e5 100644 --- a/src/sched.rs +++ b/src/sched.rs @@ -1,131 +1,144 @@ -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; +#[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 isize + 'a>; + pub type CloneCb<'a> = Box isize + 'a>; -#[repr(C)] -#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] -pub struct CpuSet { - cpu_set: libc::cpu_set_t, -} - -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 { - if field >= 8 * mem::size_of::() { - 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::() { - Err(Error::Sys(Errno::EINVAL)) - } else { - Ok(unsafe { libc::CPU_SET(field, &mut self.cpu_set) }) + pub fn is_set(&self, field: usize) -> Result { + if field >= 8 * mem::size_of::() { + 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::() { - 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::() { + 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::() as libc::size_t, - &cpuset.cpu_set) - }; + pub fn unset(&mut self, field: usize) -> Result<()> { + if field >= 8 * mem::size_of::() { + 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::() 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) -} + /// 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() }; -pub fn clone(mut cb: CloneCb, - stack: &mut [u8], - flags: CloneFlags, - signal: Option) - -> Result { - extern "C" fn callback(data: *mut CloneCb) -> c_int { - let cb: &mut CloneCb = unsafe { &mut *data }; - (*cb)() as c_int + Errno::result(res).map(drop) } - 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 clone( + mut cb: CloneCb, + stack: &mut [u8], + flags: CloneFlags, + signal: Option, + ) -> Result { + extern "C" fn callback(data: *mut CloneCb) -> c_int { + let cb: &mut CloneCb = unsafe { &mut *data }; + (*cb)() as c_int + } -pub fn unshare(flags: CloneFlags) -> Result<()> { - let res = unsafe { libc::unshare(flags.bits()) }; + 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) + } - 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()) }; + + Errno::result(res).map(drop) + } } From 04ce54b4ff098ea1f44a99f3a2ae083f956c911f Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 25 Jun 2019 10:00:59 +0200 Subject: [PATCH 2/3] Enable sched_yield for all *nix hosts --- src/sched.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/sched.rs b/src/sched.rs index ec4d0618e5..064fc29dc9 100644 --- a/src/sched.rs +++ b/src/sched.rs @@ -1,3 +1,6 @@ +use libc; +use {Errno, Result}; + #[cfg(any(target_os = "android", target_os = "linux"))] pub use self::sched_linux_like::*; @@ -93,15 +96,6 @@ mod sched_linux_like { Errno::result(res).map(drop) } - /// 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) - } - pub fn clone( mut cb: CloneCb, stack: &mut [u8], @@ -142,3 +136,12 @@ mod sched_linux_like { Errno::result(res).map(drop) } } + +/// 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) +} From b9a21abb51af1823c2510268d19a5a8ca40d9bdf Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 25 Jun 2019 10:07:41 +0200 Subject: [PATCH 3/3] Document changes in CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb440cab40..b3d7089e5e 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