1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
//! Explicit real-time promotion - the consent API.
//!
//! [`set_thread_priority`](crate::set_thread_priority) is deliberately
//! timeshare-only on Linux: a real-time thread that spins owns its core
//! until the kernel's throttle or an `RLIMIT_RTTIME` SIGKILL intervenes, and
//! that trade-off belongs to the application, not to a library default.
//! These functions are the opt-in.
use Duration;
use crate::;
/// Promotes the current thread to the platform's real-time tier.
///
/// `budget` is the thread's promise: the longest stretch it will compute
/// without blocking (an audio feeder filling a 5 ms buffer might promise
/// 1 ms). Keep it honest and small.
///
/// # Platform behavior
///
/// * **Linux** - tries, in order: direct `SCHED_RR` 85 (root, `CAP_SYS_NICE`,
/// raised `RLIMIT_RTPRIO`), the xdg realtime portal (the path that works
/// inside Flatpak), and rtkit (plain desktops, Steam's pressure-vessel).
/// The brokered paths require an `RLIMIT_RTTIME` and this function sets it:
/// soft = `budget` (delivers a catchable `SIGXCPU` warning), hard = the
/// daemon's ceiling (default 200 ms - delivers **SIGKILL to the whole
/// process**). The budget meter resets on every blocking syscall: being
/// late is fine, spinning forever is fatal. Lowering the hard limit is
/// irreversible and process-wide - that is the consent this call signs.
/// The granted RT priority over the brokered paths is the daemon's maximum
/// (default 20), not 85 - still above every timeshare thread.
/// * **macOS** - `SCHED_RR` 47 fixed priority (no decay), no privileges
/// needed, no leash; `budget` is unused. Per Apple's `qos.h` the thread
/// PERMANENTLY leaves the QoS system - dedicate it.
/// * **Windows** - `THREAD_PRIORITY_TIME_CRITICAL`; `budget` is unused, no
/// leash (the dynamic-priority band, not `REALTIME_PRIORITY_CLASS`).
///
/// A denied Linux promotion returns an [`AppliedPriority`] whose effective
/// level and mechanism report the timeshare state the thread kept, with
/// [`crate::FallbackReason`] and [`crate::BrokerError`] carrying the broker
/// result when one answered. Other platform failures that prevent even asking
/// for realtime remain [`crate::Error`] values.
///
/// # Do not install signal handlers for this
///
/// The library installs none. If you want the `SIGXCPU` warning on Linux,
/// handle it yourself (set a flag, then call
/// [`demote_thread_from_realtime`] from the thread) - self-demotion before
/// the hard limit is the recovery path, a library-owned handler would fight
/// the application's own signal management.
/// Returns the current thread from the real-time tier to normal scheduling.
///
/// This is the self-demotion half of the consent: call it when the
/// real-time phase ends, or from your own watchdog when a `SIGXCPU` warning
/// fired. On Linux the thread goes back to `SCHED_OTHER` (the lowered hard
/// `RLIMIT_RTTIME` remains - irreversible - but stops mattering once no
/// thread runs real-time). On macOS, a thread that never entered fixed-priority
/// scheduling is set to QoS Normal; a thread that did enter `SCHED_RR` cannot
/// rejoin QoS and lands on the legacy `SCHED_OTHER` band at Normal strength.
/// On Windows it returns to `THREAD_PRIORITY_NORMAL`.