Skip to content

Commit faaad04

Browse files
authored
Merge pull request #16 from vityafx/osx
Add macOS support.
2 parents 58cc2cb + 73ca1fa commit faaad04

File tree

4 files changed

+116
-37
lines changed

4 files changed

+116
-37
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "thread-priority"
3-
version = "0.4.1"
3+
version = "0.5.0"
44
authors = ["Victor Polevoy <[email protected]>"]
55
description = "Library for managing threads priority and schedule policies"
66
repository = "https://github.com/vityafx/thread-priority"
@@ -14,7 +14,7 @@ edition = "2018"
1414
[dependencies]
1515
log = "0.4"
1616

17-
[target.'cfg(unix)'.dependencies]
17+
[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd"))'.dependencies]
1818
libc = "0.2"
1919

2020
[target.'cfg(windows)'.dependencies]

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@
77

88
A simple library to control thread schedule policies and thread priority.
99

10-
This crate does not support all the plaforms yet but it is inteded to be developed so,
11-
so feel free to contribute!
10+
If your operating system isn't yet supported, please, create an issue.
1211

1312
## Supported platforms
1413
- Linux
14+
- DragonFly
15+
- FreeBSD
16+
- OpenBSD
17+
- NetBSD
18+
- macOS
1519
- Windows
1620

1721
## Examples

src/lib.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,23 @@
8787
#![warn(missing_docs)]
8888
#![deny(warnings)]
8989

90-
#[cfg(unix)]
90+
#[cfg(any(
91+
target_os = "linux",
92+
target_os = "macos",
93+
target_os = "dragonfly",
94+
target_os = "freebsd",
95+
target_os = "openbsd",
96+
target_os = "netbsd"
97+
))]
9198
pub mod unix;
92-
#[cfg(unix)]
99+
#[cfg(any(
100+
target_os = "linux",
101+
target_os = "macos",
102+
target_os = "dragonfly",
103+
target_os = "freebsd",
104+
target_os = "openbsd",
105+
target_os = "netbsd"
106+
))]
93107
pub use unix::*;
94108

95109
#[cfg(windows)]

src/unix.rs

Lines changed: 92 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
use std::convert::TryFrom;
88

99
use crate::{Error, ThreadPriority, ThreadPriorityValue};
10+
use std::mem::MaybeUninit;
1011

1112
/// An alias type for a thread id.
1213
pub type ThreadId = libc::pthread_t;
1314

1415
/// Proxy structure to maintain compatibility between glibc and musl
16+
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
1517
pub struct ScheduleParams {
1618
/// Copy of `sched_priority` from `libc::sched_param`
1719
pub sched_priority: libc::c_int,
@@ -45,30 +47,10 @@ pub struct SchedAttr {
4547
}
4648

4749
impl ScheduleParams {
48-
#[cfg(not(target_env = "musl"))]
4950
fn into_posix(self) -> libc::sched_param {
50-
libc::sched_param {
51-
sched_priority: self.sched_priority,
52-
}
53-
}
54-
55-
#[cfg(target_env = "musl")]
56-
fn into_posix(self) -> libc::sched_param {
57-
use libc::timespec as TimeSpec;
58-
59-
libc::sched_param {
60-
sched_priority: self.sched_priority,
61-
sched_ss_low_priority: 0,
62-
sched_ss_repl_period: TimeSpec {
63-
tv_sec: 0,
64-
tv_nsec: 0,
65-
},
66-
sched_ss_init_budget: TimeSpec {
67-
tv_sec: 0,
68-
tv_nsec: 0,
69-
},
70-
sched_ss_max_repl: 0,
71-
}
51+
let mut param = unsafe { MaybeUninit::<libc::sched_param>::zeroed().assume_init() };
52+
param.sched_priority = self.sched_priority;
53+
param
7254
}
7355

7456
fn from_posix(sched_param: libc::sched_param) -> Self {
@@ -95,7 +77,10 @@ pub enum RealtimeThreadSchedulePolicy {
9577
impl RealtimeThreadSchedulePolicy {
9678
fn to_posix(self) -> libc::c_int {
9779
match self {
80+
#[cfg(not(target_os = "macos"))]
9881
RealtimeThreadSchedulePolicy::Fifo => 1,
82+
#[cfg(target_os = "macos")]
83+
RealtimeThreadSchedulePolicy::Fifo => 4,
9984
RealtimeThreadSchedulePolicy::RoundRobin => 2,
10085
#[cfg(target_os = "linux")]
10186
RealtimeThreadSchedulePolicy::Deadline => 6,
@@ -116,13 +101,22 @@ pub enum NormalThreadSchedulePolicy {
116101
Normal,
117102
}
118103
impl NormalThreadSchedulePolicy {
104+
#[cfg(not(target_os = "macos"))]
119105
fn to_posix(self) -> libc::c_int {
120106
match self {
121107
NormalThreadSchedulePolicy::Idle => 5,
122108
NormalThreadSchedulePolicy::Batch => 3,
123109
NormalThreadSchedulePolicy::Other | NormalThreadSchedulePolicy::Normal => 0,
124110
}
125111
}
112+
113+
#[cfg(target_os = "macos")]
114+
fn to_posix(self) -> libc::c_int {
115+
match self {
116+
NormalThreadSchedulePolicy::Other => 1,
117+
_ => panic!("Invalid value for berkley schedule policy."),
118+
}
119+
}
126120
}
127121

128122
/// Thread schedule policy definition
@@ -141,6 +135,7 @@ impl ThreadSchedulePolicy {
141135
}
142136
}
143137

138+
#[cfg(not(target_os = "macos"))]
144139
fn from_posix(policy: libc::c_int) -> Result<ThreadSchedulePolicy, Error> {
145140
match policy {
146141
0 => Ok(ThreadSchedulePolicy::Normal(
@@ -165,6 +160,24 @@ impl ThreadSchedulePolicy {
165160
_ => Err(Error::Ffi("Can't parse schedule policy from posix")),
166161
}
167162
}
163+
164+
#[cfg(target_os = "macos")]
165+
fn from_posix(policy: libc::c_int) -> Result<ThreadSchedulePolicy, Error> {
166+
match policy {
167+
1 => Ok(ThreadSchedulePolicy::Normal(
168+
NormalThreadSchedulePolicy::Other,
169+
)),
170+
4 => Ok(ThreadSchedulePolicy::Realtime(
171+
RealtimeThreadSchedulePolicy::Fifo,
172+
)),
173+
2 => Ok(ThreadSchedulePolicy::Realtime(
174+
RealtimeThreadSchedulePolicy::RoundRobin,
175+
)),
176+
_ => Err(Error::Ffi(
177+
"Can't parse schedule policy from berkley values",
178+
)),
179+
}
180+
}
168181
}
169182

170183
impl ThreadPriority {
@@ -243,14 +256,32 @@ impl ThreadPriority {
243256
///
244257
/// Setting thread priority to minimum with normal schedule policy:
245258
///
246-
/// ```rust
247-
/// use thread_priority::*;
248-
///
249-
/// let thread_id = thread_native_id();
250-
/// assert!(set_thread_priority_and_policy(thread_id,
251-
/// ThreadPriority::Min,
252-
/// ThreadSchedulePolicy::Normal(NormalThreadSchedulePolicy::Normal)).is_ok());
253-
/// ```
259+
#[cfg_attr(
260+
target_os = "macos",
261+
doc = "\
262+
```rust
263+
use thread_priority::*;
264+
265+
let thread_id = thread_native_id();
266+
assert!(set_thread_priority_and_policy(thread_id,
267+
ThreadPriority::Min,
268+
ThreadSchedulePolicy::Normal(NormalThreadSchedulePolicy::Other)).is_ok());
269+
```
270+
"
271+
)]
272+
#[cfg_attr(
273+
not(target_os = "macos"),
274+
doc = "\
275+
```rust
276+
use thread_priority::*;
277+
278+
let thread_id = thread_native_id();
279+
assert!(set_thread_priority_and_policy(thread_id,
280+
ThreadPriority::Min,
281+
ThreadSchedulePolicy::Normal(NormalThreadSchedulePolicy::Normal)).is_ok());
282+
```
283+
"
284+
)]
254285
pub fn set_thread_priority_and_policy(
255286
native: ThreadId,
256287
priority: ThreadPriority,
@@ -268,6 +299,9 @@ pub fn set_thread_priority_and_policy(
268299
/// Set current thread's priority.
269300
pub fn set_current_thread_priority(priority: ThreadPriority) -> Result<(), Error> {
270301
let thread_id = thread_native_id();
302+
#[cfg(target_os = "macos")]
303+
let policy = ThreadSchedulePolicy::Normal(NormalThreadSchedulePolicy::Other);
304+
#[cfg(not(target_os = "macos"))]
271305
let policy = ThreadSchedulePolicy::Normal(NormalThreadSchedulePolicy::Normal);
272306
set_thread_priority_and_policy(thread_id, priority, policy)
273307
}
@@ -281,6 +315,7 @@ pub fn set_current_thread_priority(priority: ThreadPriority) -> Result<(), Error
281315
///
282316
/// assert!(thread_schedule_policy().is_ok());
283317
/// ```
318+
#[cfg(not(target_os = "macos"))]
284319
pub fn thread_schedule_policy() -> Result<ThreadSchedulePolicy, Error> {
285320
unsafe { ThreadSchedulePolicy::from_posix(libc::sched_getscheduler(libc::getpid())) }
286321
}
@@ -511,6 +546,32 @@ mod tests {
511546
assert!(thread_schedule_policy_param(thread_id).is_ok());
512547
}
513548

549+
#[cfg(target_os = "macos")]
550+
#[test]
551+
fn set_thread_priority_test() {
552+
let thread_id = thread_native_id();
553+
554+
assert!(set_thread_priority_and_policy(
555+
thread_id,
556+
ThreadPriority::Min,
557+
ThreadSchedulePolicy::Normal(NormalThreadSchedulePolicy::Other)
558+
)
559+
.is_ok());
560+
assert!(set_thread_priority_and_policy(
561+
thread_id,
562+
ThreadPriority::Max,
563+
ThreadSchedulePolicy::Normal(NormalThreadSchedulePolicy::Other)
564+
)
565+
.is_ok());
566+
assert!(set_thread_priority_and_policy(
567+
thread_id,
568+
ThreadPriority::Specific(0),
569+
ThreadSchedulePolicy::Normal(NormalThreadSchedulePolicy::Other)
570+
)
571+
.is_ok());
572+
}
573+
574+
#[cfg(not(target_os = "macos"))]
514575
#[test]
515576
fn set_thread_priority_test() {
516577
let thread_id = thread_native_id();

0 commit comments

Comments
 (0)