summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Zoeller <rtzoeller@rtzoeller.com>2021-09-22 14:48:12 -0500
committerRyan Zoeller <rtzoeller@rtzoeller.com>2021-12-22 13:56:16 -0600
commit1fbdd29d45757360ad4c12663374879ac1f1a9bd (patch)
tree2be229e42fe2d8226fe290a750b479f411d32a65
parente2298bb098e6a37b0c4f39f4e1d5b06a9b9243e2 (diff)
downloadnix-1fbdd29d45757360ad4c12663374879ac1f1a9bd.zip
Enable sched_get/setaffinity on DragonFly BSD
-rw-r--r--CHANGELOG.md2
-rw-r--r--src/sched.rs119
-rw-r--r--test/test.rs1
3 files changed, 68 insertions, 54 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 319e19ad..c1f06dd6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
(#[1567](https://github.com/nix-rust/nix/pull/1567))
- Added `fdatasync` for FreeBSD, Fuchsia, NetBSD, and OpenBSD.
(#[1581](https://github.com/nix-rust/nix/pull/1581))
+- Added `sched_setaffinity` and `sched_getaffinity` on DragonFly.
+ (#[1537](https://github.com/nix-rust/nix/pull/1537))
### Changed
### Fixed
diff --git a/src/sched.rs b/src/sched.rs
index e888045c..e736f8d2 100644
--- a/src/sched.rs
+++ b/src/sched.rs
@@ -87,6 +87,71 @@ mod sched_linux_like {
/// Type for the function executed by [`clone`].
pub type CloneCb<'a> = Box<dyn FnMut() -> isize + 'a>;
+ /// `clone` create a child process
+ /// ([`clone(2)`](https://man7.org/linux/man-pages/man2/clone.2.html))
+ ///
+ /// `stack` is a reference to an array which will hold the stack of the new
+ /// process. Unlike when calling `clone(2)` from C, the provided stack
+ /// address need not be the highest address of the region. Nix will take
+ /// care of that requirement. The user only needs to provide a reference to
+ /// a normally allocated buffer.
+ 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().add(stack.len());
+ let ptr_aligned = ptr.sub(ptr as usize % 16);
+ libc::clone(
+ mem::transmute(
+ callback as extern "C" fn(*mut Box<dyn 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)
+ }
+
+ /// disassociate parts of the process execution context
+ ///
+ /// See also [unshare(2)](https://man7.org/linux/man-pages/man2/unshare.2.html)
+ pub fn unshare(flags: CloneFlags) -> Result<()> {
+ let res = unsafe { libc::unshare(flags.bits()) };
+
+ Errno::result(res).map(drop)
+ }
+
+ /// reassociate thread with a namespace
+ ///
+ /// See also [setns(2)](https://man7.org/linux/man-pages/man2/setns.2.html)
+ pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> {
+ let res = unsafe { libc::setns(fd, nstype.bits()) };
+
+ Errno::result(res).map(drop)
+ }
+}
+
+#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "linux"))]
+pub use self::sched_affinity::*;
+
+#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "linux"))]
+mod sched_affinity {
+ use crate::errno::Errno;
+ use std::mem;
+ use crate::unistd::Pid;
+ use crate::Result;
+
/// CpuSet represent a bit-mask of CPUs.
/// CpuSets are used by sched_setaffinity and
/// sched_getaffinity for example.
@@ -217,60 +282,6 @@ mod sched_linux_like {
Errno::result(res).and(Ok(cpuset))
}
-
- /// `clone` create a child process
- /// ([`clone(2)`](https://man7.org/linux/man-pages/man2/clone.2.html))
- ///
- /// `stack` is a reference to an array which will hold the stack of the new
- /// process. Unlike when calling `clone(2)` from C, the provided stack
- /// address need not be the highest address of the region. Nix will take
- /// care of that requirement. The user only needs to provide a reference to
- /// a normally allocated buffer.
- 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().add(stack.len());
- let ptr_aligned = ptr.sub(ptr as usize % 16);
- libc::clone(
- mem::transmute(
- callback as extern "C" fn(*mut Box<dyn 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)
- }
-
- /// disassociate parts of the process execution context
- ///
- /// See also [unshare(2)](https://man7.org/linux/man-pages/man2/unshare.2.html)
- pub fn unshare(flags: CloneFlags) -> Result<()> {
- let res = unsafe { libc::unshare(flags.bits()) };
-
- Errno::result(res).map(drop)
- }
-
- /// reassociate thread with a namespace
- ///
- /// See also [setns(2)](https://man7.org/linux/man-pages/man2/setns.2.html)
- pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> {
- let res = unsafe { libc::setns(fd, nstype.bits()) };
-
- Errno::result(res).map(drop)
- }
}
/// Explicitly yield the processor to other threads.
diff --git a/test/test.rs b/test/test.rs
index aade937a..922caa5f 100644
--- a/test/test.rs
+++ b/test/test.rs
@@ -29,6 +29,7 @@ mod test_poll;
#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
mod test_pty;
#[cfg(any(target_os = "android",
+ target_os = "dragonfly",
target_os = "linux"))]
mod test_sched;
#[cfg(any(target_os = "android",