summaryrefslogtreecommitdiffstats
path: root/third_party/rust/dbus/examples/rtkit.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/dbus/examples/rtkit.rs
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/dbus/examples/rtkit.rs')
-rw-r--r--third_party/rust/dbus/examples/rtkit.rs91
1 files changed, 91 insertions, 0 deletions
diff --git a/third_party/rust/dbus/examples/rtkit.rs b/third_party/rust/dbus/examples/rtkit.rs
new file mode 100644
index 0000000000..823c899bd0
--- /dev/null
+++ b/third_party/rust/dbus/examples/rtkit.rs
@@ -0,0 +1,91 @@
+/* This example asks the rtkit service to make our thread realtime priority.
+ Rtkit puts a few limitations on us to let us become realtime, such as setting
+ RLIMIT_RTTIME correctly, hence the syscalls. */
+
+extern crate dbus;
+extern crate libc;
+
+use std::cmp;
+use libc::c_int;
+
+use dbus::{Connection, BusType, Props, MessageItem, Message};
+
+/* External C stuff. Currently only working for x86_64 */
+
+#[allow(non_upper_case_globals)]
+#[cfg(target_arch = "x86_64")]
+static SYS_gettid: c_int = 186;
+
+static RLIMIT_RTTIME: c_int = 15;
+
+#[repr(C)]
+#[cfg(target_arch = "x86_64")]
+#[derive(Copy, Clone)]
+struct rlimit {
+ rlim_cur: u64,
+ rlim_max: u64,
+}
+
+extern "C" {
+ fn syscall(num: c_int, ...) -> c_int;
+
+ fn getrlimit(resource: c_int, rlim: *mut rlimit) -> c_int;
+ fn setrlimit(resource: c_int, rlim: *const rlimit) -> c_int;
+}
+
+fn item_as_i64(i: MessageItem) -> Result<i64, Box<std::error::Error>> {
+ match i {
+ MessageItem::Int32(i) => Ok(i as i64),
+ MessageItem::Int64(i) => Ok(i),
+ _ => Err(Box::from(&*format!("Property is not integer ({:?})", i)))
+ }
+}
+
+fn rtkit_set_realtime(c: &Connection, thread: u64, prio: u32) -> Result<(), ::dbus::Error> {
+ let mut m = Message::new_method_call("org.freedesktop.RealtimeKit1", "/org/freedesktop/RealtimeKit1",
+ "org.freedesktop.RealtimeKit1", "MakeThreadRealtime").unwrap();
+ m.append_items(&[thread.into(), prio.into()]);
+ let mut r = try!(c.send_with_reply_and_block(m, 10000));
+ r.as_result().map(|_| ())
+}
+
+fn make_realtime(prio: u32) -> Result<u32, Box<std::error::Error>> {
+ let c = try!(Connection::get_private(BusType::System));
+
+ let p = Props::new(&c, "org.freedesktop.RealtimeKit1", "/org/freedesktop/RealtimeKit1",
+ "org.freedesktop.RealtimeKit1", 10000);
+
+ // Make sure we don't fail by wanting too much
+ let max_prio = try!(item_as_i64(try!(p.get("MaxRealtimePriority")))) as u32;
+ let prio = cmp::min(prio, max_prio);
+
+ // Enforce RLIMIT_RTPRIO, also a must before asking rtkit for rtprio
+ let max_rttime = try!(item_as_i64(try!(p.get("RTTimeNSecMax")))) as u64;
+ let new_limit = rlimit { rlim_cur: max_rttime, rlim_max: max_rttime };
+ let mut old_limit = new_limit;
+ if unsafe { getrlimit(RLIMIT_RTTIME, &mut old_limit) } < 0 {
+ return Err(Box::from("getrlimit failed"));
+ }
+ if unsafe { setrlimit(RLIMIT_RTTIME, &new_limit) } < 0 {
+ return Err(Box::from("setrlimit failed"));
+ }
+
+ // Finally, let's ask rtkit to make us realtime
+ let thread_id = unsafe { syscall(SYS_gettid) };
+ let r = rtkit_set_realtime(&c, thread_id as u64, prio);
+
+ if r.is_err() {
+ unsafe { setrlimit(RLIMIT_RTTIME, &old_limit) };
+ }
+
+ try!(r);
+ Ok(prio)
+}
+
+
+fn main() {
+ match make_realtime(5) {
+ Ok(n) => println!("Got rtprio, level {}", n),
+ Err(e) => println!("No rtprio: {}", e),
+ }
+}