aria_primitives/
thread.rs1#[cfg(target_vendor = "apple")]
10pub fn raise_scheduling_class() {
11 if let Err(error) = set_user_interactive() {
12 tracing::warn!(%error, "could not raise the thread's scheduling class");
13 }
14}
15
16#[cfg(not(target_vendor = "apple"))]
18pub fn raise_scheduling_class() {}
19
20#[cfg(target_vendor = "apple")]
23#[allow(unsafe_code, reason = "pthread QoS has no safe binding")]
24fn set_user_interactive() -> std::io::Result<()> {
25 use libc::qos_class_t::QOS_CLASS_USER_INTERACTIVE;
26
27 const TOP_OF_BAND: libc::c_int = 0;
30
31 let errno =
34 unsafe { libc::pthread_set_qos_class_self_np(QOS_CLASS_USER_INTERACTIVE, TOP_OF_BAND) };
35 if errno == 0 {
36 Ok(())
37 } else {
38 Err(std::io::Error::from_raw_os_error(errno))
39 }
40}
41
42#[cfg(all(test, target_vendor = "apple"))]
43mod tests {
44 use libc::qos_class_t::{QOS_CLASS_UNSPECIFIED, QOS_CLASS_USER_INTERACTIVE};
45
46 use super::*;
47
48 #[test]
49 #[allow(unsafe_code, reason = "reading the QoS back has no safe binding")]
50 fn sets_the_calling_thread_to_user_interactive() {
51 std::thread::spawn(|| {
52 set_user_interactive().expect("set the QoS");
53 let mut class = QOS_CLASS_UNSPECIFIED;
54 let mut relative_priority = 0;
55 let errno = unsafe {
59 libc::pthread_get_qos_class_np(
60 libc::pthread_self(),
61 &mut class,
62 &mut relative_priority,
63 )
64 };
65 assert_eq!(errno, 0);
66 assert_eq!(class as u32, QOS_CLASS_USER_INTERACTIVE as u32);
67 })
68 .join()
69 .expect("thread panicked");
70 }
71}