diff --git a/src/lib.rs b/src/lib.rs index dd74009..a62cdd7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -246,19 +246,23 @@ impl std::error::Error for Error {} pub struct ThreadPriorityValue(u8); impl ThreadPriorityValue { /// The maximum value for a thread priority. - pub const MAX: u8 = 99; + pub const MAX: u8 = if cfg!(target_os = "vxworks") { 255 } else { 99 }; /// The minimum value for a thread priority. pub const MIN: u8 = 0; } impl std::convert::TryFrom for ThreadPriorityValue { - type Error = &'static str; + type Error = String; fn try_from(value: u8) -> Result { if (Self::MIN..=Self::MAX).contains(&value) { Ok(Self(value)) } else { - Err("The value is not in the range of [0;99]") + Err(format!( + "The value is not in the range of [{}; {}]", + Self::MIN, + Self::MAX + )) } } } @@ -810,7 +814,7 @@ pub trait ThreadScopeExt<'scope> { } #[rustversion::since(1.63)] -impl<'scope, 'env> ThreadScopeExt<'scope> for std::thread::Scope<'scope, 'env> { +impl<'scope> ThreadScopeExt<'scope> for std::thread::Scope<'scope, '_> { fn spawn_with_priority( &'scope self, priority: ThreadPriority, diff --git a/src/unix.rs b/src/unix.rs index f6aad7f..5a33a19 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -10,6 +10,8 @@ use std::convert::TryFrom; use libc::SCHED_NORMAL as SCHED_OTHER; #[cfg(not(target_os = "android"))] use libc::SCHED_OTHER; +#[cfg(target_os = "vxworks")] +use libc::SCHED_SPORADIC; #[cfg(any(target_os = "linux", target_os = "android"))] use libc::{SCHED_BATCH, SCHED_IDLE}; use libc::{SCHED_FIFO, SCHED_RR}; @@ -51,6 +53,8 @@ fn errno() -> libc::c_int { *libc::__errno_location() } else if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))] { *libc::__error() + } else if #[cfg(target_os = "vxworks")] { + libc::errnoGet() } else { compile_error!("Your OS is probably not supported.") } @@ -67,6 +71,8 @@ fn set_errno(number: libc::c_int) { *libc::__errno_location() = number; } else if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))] { *libc::__error() = number; + } else if #[cfg(target_os = "vxworks")] { + let _ = libc::errnoSet(number); } else { compile_error!("Your OS is probably not supported.") } @@ -171,6 +177,10 @@ pub enum RealtimeThreadSchedulePolicy { Fifo, /// A round-robin policy RoundRobin, + // Policy similar to Fifo + /// A sporadic scheduling policy specific to VxWorks. + #[cfg(target_os = "vxworks")] + Sporadic, /// A deadline policy. Note, due to Linux expecting a pid_t and not a pthread_t, the given /// [ThreadId](struct.ThreadId) will be interpreted as a pid_t. This policy is NOT /// POSIX-compatible, so we only include it for linux targets. @@ -186,6 +196,8 @@ impl RealtimeThreadSchedulePolicy { match self { RealtimeThreadSchedulePolicy::Fifo => SCHED_FIFO, RealtimeThreadSchedulePolicy::RoundRobin => SCHED_RR, + #[cfg(target_os = "vxworks")] + RealtimeThreadSchedulePolicy::Sporadic => SCHED_SPORADIC, #[cfg(all( any(target_os = "linux", target_os = "android"), not(target_arch = "wasm32") @@ -284,6 +296,10 @@ impl ThreadSchedulePolicy { SCHED_RR => Ok(ThreadSchedulePolicy::Realtime( RealtimeThreadSchedulePolicy::RoundRobin, )), + #[cfg(target_os = "vxworks")] + SCHED_SPORADIC => Ok(ThreadSchedulePolicy::Realtime( + RealtimeThreadSchedulePolicy::Sporadic, + )), #[cfg(all( any(target_os = "linux", target_os = "android"), not(target_arch = "wasm32") @@ -346,8 +362,8 @@ impl ThreadPriority { PriorityPolicyEdgeValueType::Maximum => NICENESS_MAX as libc::c_int, }) } - } else if #[cfg(any(target_os = "macos", target_os = "ios"))] { - // macOS/iOS allows specifying the priority using sched params. + } else if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "vxworks"))] { + // macOS/iOS and VxWorks allow specifying the priority using sched params. get_edge_priority(policy) } else { Err(Error::Priority( @@ -426,14 +442,14 @@ impl ThreadPriority { // for the SCHED_OTHER policy. // #[cfg(all( - any(target_os = "macos", target_os = "ios"), + any(target_os = "macos", target_os = "ios", target_os = "vxworks"), not(target_arch = "wasm32") ))] ThreadSchedulePolicy::Normal(_) => { Self::to_allowed_value_for_policy(p as i32, policy).map(|v| v as u32) } #[cfg(not(all( - any(target_os = "macos", target_os = "ios"), + any(target_os = "macos", target_os = "ios", target_os = "vxworks"), not(target_arch = "wasm32") )))] ThreadSchedulePolicy::Normal(_) => { @@ -571,10 +587,14 @@ pub fn set_thread_priority_and_policy( } _ => { let fixed_priority = priority.to_posix(policy)?; - // On macOS and iOS it is possible to set the priority + // On VxWorks, macOS and iOS it is possible to set the priority // this way. if matches!(policy, ThreadSchedulePolicy::Realtime(_)) - || cfg!(any(target_os = "macos", target_os = "ios")) + || cfg!(any( + target_os = "macos", + target_os = "ios", + target_os = "vxworks" + )) { // If the policy is a realtime one, the priority is set via // pthread_setschedparam. @@ -596,6 +616,20 @@ pub fn set_thread_priority_and_policy( e => Err(Error::OS(e)), } } else { + //VxWorks does not have set priority function + #[cfg(target_os = "vxworks")] + unsafe fn setpriority( + _which: u32, + _who: u32, + _priority: libc::c_int, + ) -> libc::c_int { + set_errno(libc::ENOSYS); + -1 + } + + #[cfg(not(target_os = "vxworks"))] + use libc::setpriority; + // Normal priority threads must be set with static priority 0. let params = ScheduleParams { sched_priority: 0 }.into_posix(); @@ -613,7 +647,7 @@ pub fn set_thread_priority_and_policy( // Normal priority threads adjust relative priority through niceness. set_errno(0); - let ret = unsafe { libc::setpriority(libc::PRIO_PROCESS, 0, fixed_priority) }; + let ret = unsafe { setpriority(libc::PRIO_PROCESS, 0, fixed_priority) }; if ret != 0 { return Err(Error::OS(errno())); } diff --git a/tests/unix.rs b/tests/unix.rs index ff144c2..e699ef7 100644 --- a/tests/unix.rs +++ b/tests/unix.rs @@ -46,6 +46,7 @@ fn get_and_set_priority_with_normal_policies( #[cfg(any( target_os = "macos", target_os = "openbsd", + target_os = "vxworks", target_os = "freebsd", target_os = "netbsd" ))] @@ -107,6 +108,7 @@ fn set_priority_with_normal_policy_but_with_invalid_value(#[case] policy: Thread #[cfg(any( target_os = "macos", target_os = "openbsd", + target_os = "vxworks", target_os = "freebsd", target_os = "netbsd" ))]