From c13302d87e7071081637421577b589c6c9183af7 Mon Sep 17 00:00:00 2001
From: Greg V <greg@unrelenting.technology>
Date: Mon, 22 Jan 2018 19:44:59 +0300
Subject: [PATCH] Add rtprio (realtime priority) API for FreeBSD and DragonFly

---
 libc-test/build.rs                        |  6 ++++--
 src/unix/bsd/freebsdlike/dragonfly/mod.rs | 10 ++++++++++
 src/unix/bsd/freebsdlike/freebsd/mod.rs   |  8 ++++++++
 src/unix/bsd/freebsdlike/mod.rs           | 12 ++++++++++++
 4 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/libc-test/build.rs b/libc-test/build.rs
index a2068154..56bc6f1f 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -288,6 +288,7 @@ fn main() {
         cfg.header("sys/msg.h");
         cfg.header("sys/shm.h");
         cfg.header("sys/procdesc.h");
+        cfg.header("sys/rtprio.h");
     }
 
     if netbsd {
@@ -311,6 +312,7 @@ fn main() {
         cfg.header("ufs/ufs/quota.h");
         cfg.header("pthread_np.h");
         cfg.header("sys/ioctl_compat.h");
+        cfg.header("sys/rtprio.h");
     }
 
     if solaris {
@@ -381,9 +383,9 @@ fn main() {
                 }
             }
             "u64" if struct_ == "epoll_event" => "data.u64".to_string(),
-            "type_" if linux &&
+            "type_" if (linux || freebsd || dragonfly) &&
                 (struct_ == "input_event" || struct_ == "input_mask" ||
-                 struct_ == "ff_effect") => "type".to_string(),
+                 struct_ == "ff_effect" || struct_ == "rtprio") => "type".to_string(),
             s => s.to_string(),
         }
     });
diff --git a/src/unix/bsd/freebsdlike/dragonfly/mod.rs b/src/unix/bsd/freebsdlike/dragonfly/mod.rs
index 620fad44..f399f27c 100644
--- a/src/unix/bsd/freebsdlike/dragonfly/mod.rs
+++ b/src/unix/bsd/freebsdlike/dragonfly/mod.rs
@@ -1,5 +1,6 @@
 pub type clock_t = u64;
 pub type ino_t = u64;
+pub type lwpid_t = i32;
 pub type nlink_t = u32;
 pub type blksize_t = i64;
 pub type clockid_t = ::c_ulong;
@@ -737,6 +738,12 @@ pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 127;
 pub const WCONTINUED: ::c_int = 4;
 pub const WSTOPPED: ::c_int = 0o177;
 
+// Values for struct rtprio (type_ field)
+pub const RTP_PRIO_REALTIME: ::c_ushort = 0;
+pub const RTP_PRIO_NORMAL: ::c_ushort = 1;
+pub const RTP_PRIO_IDLE: ::c_ushort = 2;
+pub const RTP_PRIO_THREAD: ::c_ushort = 3;
+
 extern {
     pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int)
                     -> ::c_int;
@@ -750,4 +757,7 @@ extern {
                             timeout: *mut ::timespec) -> ::c_int;
 
     pub fn freelocale(loc: ::locale_t);
+
+    pub fn lwp_rtprio(function: ::c_int, pid: ::pid_t, lwpid: lwpid_t,
+                      rtp: *mut super::rtprio) -> ::c_int;
 }
diff --git a/src/unix/bsd/freebsdlike/freebsd/mod.rs b/src/unix/bsd/freebsdlike/freebsd/mod.rs
index 5afb42aa..1e5f4f03 100644
--- a/src/unix/bsd/freebsdlike/freebsd/mod.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/mod.rs
@@ -846,6 +846,11 @@ pub const PD_DAEMON: ::c_int = 0x00000001;
 pub const PD_CLOEXEC: ::c_int = 0x00000002;
 pub const PD_ALLOWED_AT_FORK: ::c_int = PD_DAEMON | PD_CLOEXEC;
 
+// Values for struct rtprio (type_ field)
+pub const RTP_PRIO_REALTIME: ::c_ushort = 2;
+pub const RTP_PRIO_NORMAL: ::c_ushort = 3;
+pub const RTP_PRIO_IDLE: ::c_ushort = 4;
+
 extern {
     pub fn __error() -> *mut ::c_int;
 
@@ -905,6 +910,9 @@ extern {
     pub fn pdfork(fdp: *mut ::c_int, flags: ::c_int) -> ::pid_t;
     pub fn pdgetpid(fd: ::c_int, pidp: *mut ::pid_t) -> ::c_int;
     pub fn pdkill(fd: ::c_int, signum: ::c_int) -> ::c_int;
+
+    pub fn rtprio_thread(function: ::c_int, lwpid: ::lwpid_t,
+                         rtp: *mut super::rtprio) -> ::c_int;
 }
 
 cfg_if! {
diff --git a/src/unix/bsd/freebsdlike/mod.rs b/src/unix/bsd/freebsdlike/mod.rs
index 80a66b73..df32d2c4 100644
--- a/src/unix/bsd/freebsdlike/mod.rs
+++ b/src/unix/bsd/freebsdlike/mod.rs
@@ -170,6 +170,11 @@ s! {
         pub cmcred_ngroups: ::c_short,
         pub cmcred_groups: [::gid_t; CMGROUP_MAX],
     }
+
+    pub struct rtprio {
+        pub type_: ::c_ushort,
+        pub prio: ::c_ushort,
+    }
 }
 
 pub const AIO_LISTIO_MAX: ::c_int = 16;
@@ -960,6 +965,12 @@ pub const CMGROUP_MAX: usize = 16;
 // sizeof(long)
 pub const BPF_ALIGNMENT: ::c_int = 8;
 
+// Values for rtprio struct (prio field) and syscall (function argument)
+pub const RTP_PRIO_MIN: ::c_ushort = 0;
+pub const RTP_PRIO_MAX: ::c_ushort = 31;
+pub const RTP_LOOKUP: ::c_int = 0;
+pub const RTP_SET: ::c_int = 1;
+
 f! {
     pub fn WIFCONTINUED(status: ::c_int) -> bool {
         status == 0x13
@@ -1135,6 +1146,7 @@ extern {
                                          val: ::c_int) -> ::c_int;
     pub fn getpriority(which: ::c_int, who: ::c_int) -> ::c_int;
     pub fn setpriority(which: ::c_int, who: ::c_int, prio: ::c_int) -> ::c_int;
+    pub fn rtprio(function: ::c_int, pid: ::pid_t, rtp: *mut rtprio) -> ::c_int;
 
     pub fn fdopendir(fd: ::c_int) -> *mut ::DIR;
 
-- 
GitLab