Skip to content

Commit

Permalink
Add VxWorks support in unix module
Browse files Browse the repository at this point in the history
Update src/unix.rs for vxWorks tests

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
  • Loading branch information
biabbas and coderabbitai[bot] committed Nov 4, 2024
1 parent 77360b7 commit d4cec67
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 11 deletions.
12 changes: 8 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8> for ThreadPriorityValue {
type Error = &'static str;
type Error = String;

fn try_from(value: u8) -> Result<Self, Self::Error> {
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
))
}
}
}
Expand Down Expand Up @@ -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<F, T>(
&'scope self,
priority: ThreadPriority,
Expand Down
48 changes: 41 additions & 7 deletions src/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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.")
}
Expand All @@ -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.")
}
Expand Down Expand Up @@ -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.
Expand All @@ -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")
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -426,14 +442,14 @@ impl ThreadPriority {
// for the SCHED_OTHER policy.
// <https://www.usenix.org/legacy/publications/library/proceedings/bsdcon02/full_papers/gerbarg/gerbarg_html/index.html>
#[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(_) => {
Expand Down Expand Up @@ -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.
Expand All @@ -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();

Expand All @@ -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()));
}
Expand Down
13 changes: 13 additions & 0 deletions tests/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"
))]
Expand All @@ -64,9 +65,20 @@ fn get_and_set_priority_with_normal_policies(
#[case(ThreadSchedulePolicy::Normal(NormalThreadSchedulePolicy::Idle), 0..=0)]
#[cfg(target_os = "linux")]
#[case(ThreadSchedulePolicy::Normal(NormalThreadSchedulePolicy::Batch), -20..=19)]
#[cfg(not(target_os = "vxworks"))]
#[case(ThreadSchedulePolicy::Normal(NormalThreadSchedulePolicy::Other), -20..=19)]
#[cfg(not(target_os = "vxworks"))]
#[case(ThreadSchedulePolicy::Realtime(RealtimeThreadSchedulePolicy::Fifo), 0..=99)]
#[cfg(not(target_os = "vxworks"))]
#[case(ThreadSchedulePolicy::Realtime(RealtimeThreadSchedulePolicy::RoundRobin), 0..=99)]
#[cfg(target_os = "vxworks")]
#[case(ThreadSchedulePolicy::Normal(NormalThreadSchedulePolicy::Other), 0.=255)]
#[cfg(target_os = "vxworks")]
#[case(ThreadSchedulePolicy::Realtime(RealtimeThreadSchedulePolicy::Fifo), 0..=255)]
#[cfg(target_os = "vxworks")]
#[case(ThreadSchedulePolicy::Realtime(RealtimeThreadSchedulePolicy::RoundRobin), 0..=255)]
#[cfg(target_os = "vxworks")]
#[case(ThreadSchedulePolicy::Realtime(RealtimeThreadSchedulePolicy::Sporadic), 0..=255)]
fn check_min_and_max_priority_values(
#[case] policy: ThreadSchedulePolicy,
#[case] posix_range: std::ops::RangeInclusive<i32>,
Expand Down Expand Up @@ -107,6 +119,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"
))]
Expand Down

0 comments on commit d4cec67

Please sign in to comment.