Skip to content

Commit cc55fd2

Browse files
bors[bot]rtzoeller
andauthored
Merge #1537
1537: DragonFly BSD supports `sched_getaffinity()` and `sched_setaffinity()` r=rtzoeller a=rtzoeller Move `CpuSet`, `sched_getaffinity()`, and `sched_setaffinity()` from the `sched_linux_like` namespace to `sched_affinity`. Declare support for DragonFly BSD. `test_sched_affinity()` passes locally on DragonFly BSD. Co-authored-by: Ryan Zoeller <rtzoeller@rtzoeller.com>
2 parents e2298bb + 1fbdd29 commit cc55fd2

File tree

3 files changed

+68
-54
lines changed

3 files changed

+68
-54
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
1515
(#[1567](https://github.com/nix-rust/nix/pull/1567))
1616
- Added `fdatasync` for FreeBSD, Fuchsia, NetBSD, and OpenBSD.
1717
(#[1581](https://github.com/nix-rust/nix/pull/1581))
18+
- Added `sched_setaffinity` and `sched_getaffinity` on DragonFly.
19+
(#[1537](https://github.com/nix-rust/nix/pull/1537))
1820

1921
### Changed
2022
### Fixed

src/sched.rs

Lines changed: 65 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,71 @@ mod sched_linux_like {
8787
/// Type for the function executed by [`clone`].
8888
pub type CloneCb<'a> = Box<dyn FnMut() -> isize + 'a>;
8989

90+
/// `clone` create a child process
91+
/// ([`clone(2)`](https://man7.org/linux/man-pages/man2/clone.2.html))
92+
///
93+
/// `stack` is a reference to an array which will hold the stack of the new
94+
/// process. Unlike when calling `clone(2)` from C, the provided stack
95+
/// address need not be the highest address of the region. Nix will take
96+
/// care of that requirement. The user only needs to provide a reference to
97+
/// a normally allocated buffer.
98+
pub fn clone(
99+
mut cb: CloneCb,
100+
stack: &mut [u8],
101+
flags: CloneFlags,
102+
signal: Option<c_int>,
103+
) -> Result<Pid> {
104+
extern "C" fn callback(data: *mut CloneCb) -> c_int {
105+
let cb: &mut CloneCb = unsafe { &mut *data };
106+
(*cb)() as c_int
107+
}
108+
109+
let res = unsafe {
110+
let combined = flags.bits() | signal.unwrap_or(0);
111+
let ptr = stack.as_mut_ptr().add(stack.len());
112+
let ptr_aligned = ptr.sub(ptr as usize % 16);
113+
libc::clone(
114+
mem::transmute(
115+
callback as extern "C" fn(*mut Box<dyn FnMut() -> isize>) -> i32,
116+
),
117+
ptr_aligned as *mut c_void,
118+
combined,
119+
&mut cb as *mut _ as *mut c_void,
120+
)
121+
};
122+
123+
Errno::result(res).map(Pid::from_raw)
124+
}
125+
126+
/// disassociate parts of the process execution context
127+
///
128+
/// See also [unshare(2)](https://man7.org/linux/man-pages/man2/unshare.2.html)
129+
pub fn unshare(flags: CloneFlags) -> Result<()> {
130+
let res = unsafe { libc::unshare(flags.bits()) };
131+
132+
Errno::result(res).map(drop)
133+
}
134+
135+
/// reassociate thread with a namespace
136+
///
137+
/// See also [setns(2)](https://man7.org/linux/man-pages/man2/setns.2.html)
138+
pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> {
139+
let res = unsafe { libc::setns(fd, nstype.bits()) };
140+
141+
Errno::result(res).map(drop)
142+
}
143+
}
144+
145+
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "linux"))]
146+
pub use self::sched_affinity::*;
147+
148+
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "linux"))]
149+
mod sched_affinity {
150+
use crate::errno::Errno;
151+
use std::mem;
152+
use crate::unistd::Pid;
153+
use crate::Result;
154+
90155
/// CpuSet represent a bit-mask of CPUs.
91156
/// CpuSets are used by sched_setaffinity and
92157
/// sched_getaffinity for example.
@@ -217,60 +282,6 @@ mod sched_linux_like {
217282

218283
Errno::result(res).and(Ok(cpuset))
219284
}
220-
221-
/// `clone` create a child process
222-
/// ([`clone(2)`](https://man7.org/linux/man-pages/man2/clone.2.html))
223-
///
224-
/// `stack` is a reference to an array which will hold the stack of the new
225-
/// process. Unlike when calling `clone(2)` from C, the provided stack
226-
/// address need not be the highest address of the region. Nix will take
227-
/// care of that requirement. The user only needs to provide a reference to
228-
/// a normally allocated buffer.
229-
pub fn clone(
230-
mut cb: CloneCb,
231-
stack: &mut [u8],
232-
flags: CloneFlags,
233-
signal: Option<c_int>,
234-
) -> Result<Pid> {
235-
extern "C" fn callback(data: *mut CloneCb) -> c_int {
236-
let cb: &mut CloneCb = unsafe { &mut *data };
237-
(*cb)() as c_int
238-
}
239-
240-
let res = unsafe {
241-
let combined = flags.bits() | signal.unwrap_or(0);
242-
let ptr = stack.as_mut_ptr().add(stack.len());
243-
let ptr_aligned = ptr.sub(ptr as usize % 16);
244-
libc::clone(
245-
mem::transmute(
246-
callback as extern "C" fn(*mut Box<dyn FnMut() -> isize>) -> i32,
247-
),
248-
ptr_aligned as *mut c_void,
249-
combined,
250-
&mut cb as *mut _ as *mut c_void,
251-
)
252-
};
253-
254-
Errno::result(res).map(Pid::from_raw)
255-
}
256-
257-
/// disassociate parts of the process execution context
258-
///
259-
/// See also [unshare(2)](https://man7.org/linux/man-pages/man2/unshare.2.html)
260-
pub fn unshare(flags: CloneFlags) -> Result<()> {
261-
let res = unsafe { libc::unshare(flags.bits()) };
262-
263-
Errno::result(res).map(drop)
264-
}
265-
266-
/// reassociate thread with a namespace
267-
///
268-
/// See also [setns(2)](https://man7.org/linux/man-pages/man2/setns.2.html)
269-
pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> {
270-
let res = unsafe { libc::setns(fd, nstype.bits()) };
271-
272-
Errno::result(res).map(drop)
273-
}
274285
}
275286

276287
/// Explicitly yield the processor to other threads.

test/test.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ mod test_poll;
2929
#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
3030
mod test_pty;
3131
#[cfg(any(target_os = "android",
32+
target_os = "dragonfly",
3233
target_os = "linux"))]
3334
mod test_sched;
3435
#[cfg(any(target_os = "android",

0 commit comments

Comments
 (0)