diff --git a/libc-test/build.rs b/libc-test/build.rs
index ccb902d9e24e157fc13beb7c4589b053f09896cb..a693b0d9f25f0b620c95936ac71d92a5aa52eda5 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -13,6 +13,7 @@ fn main() {
     let apple = target.contains("apple");
     let musl = target.contains("musl");
     let freebsd = target.contains("freebsd");
+    let mips = target.contains("mips");
     let bsdlike = freebsd || apple;
     let mut cfg = ctest::TestGenerator::new();
 
@@ -112,10 +113,12 @@ fn main() {
         if !musl {
             cfg.header("linux/netlink.h");
         }
+        cfg.header("sched.h");
     }
 
     if freebsd {
         cfg.header("pthread_np.h");
+        cfg.header("sched.h");
     }
 
     cfg.type_name(move |ty, is_struct| {
@@ -222,6 +225,8 @@ fn main() {
             "RLIMIT_NLIMITS" |
             "TCP_COOKIE_TRANSACTIONS" |
             "RLIMIT_RTTIME" if musl => true,
+            // work around super old mips toolchain
+            "SCHED_IDLE" => mips,
 
             _ => false,
         }
diff --git a/src/unix/bsd/freebsdlike/mod.rs b/src/unix/bsd/freebsdlike/mod.rs
index 4826357a7f8fcdcf94dcfc20639f4c4679b48e88..dab2d036d2b9685e12c927490922d1774ca4f61e 100644
--- a/src/unix/bsd/freebsdlike/mod.rs
+++ b/src/unix/bsd/freebsdlike/mod.rs
@@ -99,6 +99,10 @@ s! {
         pub f_fsid: ::c_ulong,
         pub f_namemax: ::c_ulong,
     }
+
+    pub struct sched_param {
+        pub sched_priority: ::c_int,
+    }
 }
 
 pub const EXIT_FAILURE: ::c_int = 1;
@@ -514,6 +518,10 @@ pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = 0 as *mut _;
 pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = 0 as *mut _;
 pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 2;
 
+pub const SCHED_FIFO: ::c_int = 1;
+pub const SCHED_OTHER: ::c_int = 2;
+pub const SCHED_RR: ::c_int = 3;
+
 extern {
     pub fn mprotect(addr: *const ::c_void, len: ::size_t, prot: ::c_int)
                     -> ::c_int;
@@ -536,6 +544,8 @@ extern {
     pub fn pthread_set_name_np(tid: ::pthread_t, name: *const ::c_char);
     pub fn posix_fallocate(fd: ::c_int, offset: ::off_t,
                            len: ::off_t) -> ::c_int;
+    pub fn sched_setscheduler(pid: ::pid_t, policy: ::c_int, param: *const sched_param) -> ::c_int;
+    pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int;
 }
 
 cfg_if! {
diff --git a/src/unix/notbsd/linux/mod.rs b/src/unix/notbsd/linux/mod.rs
index 6619c1581edf09bd28b0a9cf0c0d35142160364a..ac6d8cca32e4af7c9951fa61ea94fcf968e0ad0e 100644
--- a/src/unix/notbsd/linux/mod.rs
+++ b/src/unix/notbsd/linux/mod.rs
@@ -281,6 +281,12 @@ pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
 pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1;
 pub const __SIZEOF_PTHREAD_COND_T: usize = 48;
 
+pub const SCHED_OTHER: ::c_int = 0;
+pub const SCHED_FIFO: ::c_int = 1;
+pub const SCHED_RR: ::c_int = 2;
+pub const SCHED_BATCH: ::c_int = 3;
+pub const SCHED_IDLE: ::c_int = 5;
+
 extern {
     pub fn shm_open(name: *const c_char, oflag: ::c_int,
                     mode: mode_t) -> ::c_int;
diff --git a/src/unix/notbsd/mod.rs b/src/unix/notbsd/mod.rs
index add7bb9a5b47b8a876e30ae6941dfe581847bac2..1ffb13386acac80d87b706c3ffc9b1c33dc52438 100644
--- a/src/unix/notbsd/mod.rs
+++ b/src/unix/notbsd/mod.rs
@@ -86,6 +86,18 @@ s! {
         pub tm_gmtoff: ::c_long,
         pub tm_zone: *const ::c_char,
     }
+
+    pub struct sched_param {
+        pub sched_priority: ::c_int,
+        #[cfg(target_env = "musl")]
+        pub sched_ss_low_priority: ::c_int,
+        #[cfg(target_env = "musl")]
+        pub sched_ss_repl_period: ::timespec,
+        #[cfg(target_env = "musl")]
+        pub sched_ss_init_budget: ::timespec,
+        #[cfg(target_env = "musl")]
+        pub sched_ss_max_repl: ::c_int,
+    }
 }
 
 // intentionally not public, only used for fd_set
@@ -377,6 +389,10 @@ extern {
     pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void;
     pub fn setgroups(ngroups: ::size_t,
                      ptr: *const ::gid_t) -> ::c_int;
+    pub fn sched_setscheduler(pid: ::pid_t, policy: ::c_int, param: *const sched_param) -> ::c_int;
+    pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int;
+    pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int;
+    pub fn sched_get_priority_min(policy: ::c_int) -> ::c_int;
 }
 
 cfg_if! {