Skip to content

Commit 112438b

Browse files
bors[bot]Jakub Konka
and
Jakub Konka
committed
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 <[email protected]>
2 parents dc5f8ee + b9a21ab commit 112438b

File tree

3 files changed

+126
-109
lines changed

3 files changed

+126
-109
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
2323
([#928](https://github.com/nix-rust/nix/pull/928))
2424

2525
### Fixed
26+
- Enabled `sched_yield` for all nix hosts.
27+
([#1090](https://github.com/nix-rust/nix/pull/1090))
28+
2629
### Removed
2730

2831
## [0.14.1] - 2019-06-06

src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ pub mod net;
6262
pub mod poll;
6363
#[deny(missing_docs)]
6464
pub mod pty;
65-
#[cfg(any(target_os = "android",
66-
target_os = "linux"))]
6765
pub mod sched;
6866
pub mod sys;
6967
// This can be implemented for other platforms as soon as libc

src/sched.rs

Lines changed: 123 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,131 +1,147 @@
1-
use std::mem;
2-
use std::os::unix::io::RawFd;
3-
use std::option::Option;
4-
use libc::{self, c_int, c_void};
5-
use {Error, Result};
6-
use errno::Errno;
7-
use ::unistd::Pid;
8-
9-
// For some functions taking with a parameter of type CloneFlags,
10-
// only a subset of these flags have an effect.
11-
libc_bitflags!{
12-
pub struct CloneFlags: c_int {
13-
CLONE_VM;
14-
CLONE_FS;
15-
CLONE_FILES;
16-
CLONE_SIGHAND;
17-
CLONE_PTRACE;
18-
CLONE_VFORK;
19-
CLONE_PARENT;
20-
CLONE_THREAD;
21-
CLONE_NEWNS;
22-
CLONE_SYSVSEM;
23-
CLONE_SETTLS;
24-
CLONE_PARENT_SETTID;
25-
CLONE_CHILD_CLEARTID;
26-
CLONE_DETACHED;
27-
CLONE_UNTRACED;
28-
CLONE_CHILD_SETTID;
29-
CLONE_NEWCGROUP;
30-
CLONE_NEWUTS;
31-
CLONE_NEWIPC;
32-
CLONE_NEWUSER;
33-
CLONE_NEWPID;
34-
CLONE_NEWNET;
35-
CLONE_IO;
1+
use libc;
2+
use {Errno, Result};
3+
4+
#[cfg(any(target_os = "android", target_os = "linux"))]
5+
pub use self::sched_linux_like::*;
6+
7+
#[cfg(any(target_os = "android", target_os = "linux"))]
8+
mod sched_linux_like {
9+
use errno::Errno;
10+
use libc::{self, c_int, c_void};
11+
use std::mem;
12+
use std::option::Option;
13+
use std::os::unix::io::RawFd;
14+
use unistd::Pid;
15+
use {Error, Result};
16+
17+
// For some functions taking with a parameter of type CloneFlags,
18+
// only a subset of these flags have an effect.
19+
libc_bitflags! {
20+
pub struct CloneFlags: c_int {
21+
CLONE_VM;
22+
CLONE_FS;
23+
CLONE_FILES;
24+
CLONE_SIGHAND;
25+
CLONE_PTRACE;
26+
CLONE_VFORK;
27+
CLONE_PARENT;
28+
CLONE_THREAD;
29+
CLONE_NEWNS;
30+
CLONE_SYSVSEM;
31+
CLONE_SETTLS;
32+
CLONE_PARENT_SETTID;
33+
CLONE_CHILD_CLEARTID;
34+
CLONE_DETACHED;
35+
CLONE_UNTRACED;
36+
CLONE_CHILD_SETTID;
37+
CLONE_NEWCGROUP;
38+
CLONE_NEWUTS;
39+
CLONE_NEWIPC;
40+
CLONE_NEWUSER;
41+
CLONE_NEWPID;
42+
CLONE_NEWNET;
43+
CLONE_IO;
44+
}
3645
}
37-
}
3846

39-
pub type CloneCb<'a> = Box<FnMut() -> isize + 'a>;
40-
41-
#[repr(C)]
42-
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
43-
pub struct CpuSet {
44-
cpu_set: libc::cpu_set_t,
45-
}
47+
pub type CloneCb<'a> = Box<FnMut() -> isize + 'a>;
4648

47-
impl CpuSet {
48-
pub fn new() -> CpuSet {
49-
CpuSet { cpu_set: unsafe { mem::zeroed() } }
49+
#[repr(C)]
50+
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
51+
pub struct CpuSet {
52+
cpu_set: libc::cpu_set_t,
5053
}
5154

52-
pub fn is_set(&self, field: usize) -> Result<bool> {
53-
if field >= 8 * mem::size_of::<libc::cpu_set_t>() {
54-
Err(Error::Sys(Errno::EINVAL))
55-
} else {
56-
Ok(unsafe { libc::CPU_ISSET(field, &self.cpu_set) })
55+
impl CpuSet {
56+
pub fn new() -> CpuSet {
57+
CpuSet {
58+
cpu_set: unsafe { mem::zeroed() },
59+
}
5760
}
58-
}
5961

60-
pub fn set(&mut self, field: usize) -> Result<()> {
61-
if field >= 8 * mem::size_of::<libc::cpu_set_t>() {
62-
Err(Error::Sys(Errno::EINVAL))
63-
} else {
64-
Ok(unsafe { libc::CPU_SET(field, &mut self.cpu_set) })
62+
pub fn is_set(&self, field: usize) -> Result<bool> {
63+
if field >= 8 * mem::size_of::<libc::cpu_set_t>() {
64+
Err(Error::Sys(Errno::EINVAL))
65+
} else {
66+
Ok(unsafe { libc::CPU_ISSET(field, &self.cpu_set) })
67+
}
6568
}
66-
}
6769

68-
pub fn unset(&mut self, field: usize) -> Result<()> {
69-
if field >= 8 * mem::size_of::<libc::cpu_set_t>() {
70-
Err(Error::Sys(Errno::EINVAL))
71-
} else {
72-
Ok(unsafe { libc::CPU_CLR(field, &mut self.cpu_set) })
70+
pub fn set(&mut self, field: usize) -> Result<()> {
71+
if field >= 8 * mem::size_of::<libc::cpu_set_t>() {
72+
Err(Error::Sys(Errno::EINVAL))
73+
} else {
74+
Ok(unsafe { libc::CPU_SET(field, &mut self.cpu_set) })
75+
}
7376
}
74-
}
75-
}
7677

77-
pub fn sched_setaffinity(pid: Pid, cpuset: &CpuSet) -> Result<()> {
78-
let res = unsafe {
79-
libc::sched_setaffinity(pid.into(),
80-
mem::size_of::<CpuSet>() as libc::size_t,
81-
&cpuset.cpu_set)
82-
};
78+
pub fn unset(&mut self, field: usize) -> Result<()> {
79+
if field >= 8 * mem::size_of::<libc::cpu_set_t>() {
80+
Err(Error::Sys(Errno::EINVAL))
81+
} else {
82+
Ok(unsafe { libc::CPU_CLR(field, &mut self.cpu_set) })
83+
}
84+
}
85+
}
8386

84-
Errno::result(res).map(drop)
85-
}
87+
pub fn sched_setaffinity(pid: Pid, cpuset: &CpuSet) -> Result<()> {
88+
let res = unsafe {
89+
libc::sched_setaffinity(
90+
pid.into(),
91+
mem::size_of::<CpuSet>() as libc::size_t,
92+
&cpuset.cpu_set,
93+
)
94+
};
8695

87-
/// Explicitly yield the processor to other threads.
88-
///
89-
/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_yield.html)
90-
pub fn sched_yield() -> Result<()> {
91-
let res = unsafe {
92-
libc::sched_yield()
93-
};
96+
Errno::result(res).map(drop)
97+
}
9498

95-
Errno::result(res).map(drop)
96-
}
99+
pub fn clone(
100+
mut cb: CloneCb,
101+
stack: &mut [u8],
102+
flags: CloneFlags,
103+
signal: Option<c_int>,
104+
) -> Result<Pid> {
105+
extern "C" fn callback(data: *mut CloneCb) -> c_int {
106+
let cb: &mut CloneCb = unsafe { &mut *data };
107+
(*cb)() as c_int
108+
}
97109

98-
pub fn clone(mut cb: CloneCb,
99-
stack: &mut [u8],
100-
flags: CloneFlags,
101-
signal: Option<c_int>)
102-
-> Result<Pid> {
103-
extern "C" fn callback(data: *mut CloneCb) -> c_int {
104-
let cb: &mut CloneCb = unsafe { &mut *data };
105-
(*cb)() as c_int
110+
let res = unsafe {
111+
let combined = flags.bits() | signal.unwrap_or(0);
112+
let ptr = stack.as_mut_ptr().offset(stack.len() as isize);
113+
let ptr_aligned = ptr.offset((ptr as usize % 16) as isize * -1);
114+
libc::clone(
115+
mem::transmute(
116+
callback as extern "C" fn(*mut Box<::std::ops::FnMut() -> isize>) -> i32,
117+
),
118+
ptr_aligned as *mut c_void,
119+
combined,
120+
&mut cb as *mut _ as *mut c_void,
121+
)
122+
};
123+
124+
Errno::result(res).map(Pid::from_raw)
106125
}
107126

108-
let res = unsafe {
109-
let combined = flags.bits() | signal.unwrap_or(0);
110-
let ptr = stack.as_mut_ptr().offset(stack.len() as isize);
111-
let ptr_aligned = ptr.offset((ptr as usize % 16) as isize * -1);
112-
libc::clone(mem::transmute(callback as extern "C" fn(*mut Box<::std::ops::FnMut() -> isize>) -> i32),
113-
ptr_aligned as *mut c_void,
114-
combined,
115-
&mut cb as *mut _ as *mut c_void)
116-
};
117-
118-
Errno::result(res).map(Pid::from_raw)
119-
}
127+
pub fn unshare(flags: CloneFlags) -> Result<()> {
128+
let res = unsafe { libc::unshare(flags.bits()) };
129+
130+
Errno::result(res).map(drop)
131+
}
120132

121-
pub fn unshare(flags: CloneFlags) -> Result<()> {
122-
let res = unsafe { libc::unshare(flags.bits()) };
133+
pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> {
134+
let res = unsafe { libc::setns(fd, nstype.bits()) };
123135

124-
Errno::result(res).map(drop)
136+
Errno::result(res).map(drop)
137+
}
125138
}
126139

127-
pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> {
128-
let res = unsafe { libc::setns(fd, nstype.bits()) };
140+
/// Explicitly yield the processor to other threads.
141+
///
142+
/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_yield.html)
143+
pub fn sched_yield() -> Result<()> {
144+
let res = unsafe { libc::sched_yield() };
129145

130146
Errno::result(res).map(drop)
131147
}

0 commit comments

Comments
 (0)