77use std:: convert:: TryFrom ;
88
99use crate :: { Error , ThreadPriority , ThreadPriorityValue } ;
10+ use std:: mem:: MaybeUninit ;
1011
1112/// An alias type for a thread id.
1213pub 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 ) ]
1517pub 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
4749impl 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 {
9577impl 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}
118103impl 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
170183impl 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+ ) ]
254285pub 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.
269300pub 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" ) ) ]
284319pub 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