-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpriority.rs
More file actions
116 lines (100 loc) · 3.34 KB
/
priority.rs
File metadata and controls
116 lines (100 loc) · 3.34 KB
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
107
108
109
110
111
112
113
114
115
116
//! Priority levels for task scheduling.
//!
//! [`Priority`] is a `u8` newtype where lower values mean higher priority.
//! Named constants ([`REALTIME`](Priority::REALTIME), [`HIGH`](Priority::HIGH),
//! [`NORMAL`](Priority::NORMAL), [`BACKGROUND`](Priority::BACKGROUND),
//! [`IDLE`](Priority::IDLE)) cover common tiers, and any value 0–255 is valid
//! for fine-grained control.
use std::cmp::Ordering;
use std::fmt;
use serde::{Deserialize, Serialize};
/// Numeric priority level. Lower values = higher priority.
///
/// Provides named constants for common tiers while allowing any value 0–255
/// for fine-grained control.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct Priority(u8);
impl Priority {
/// User-interactive work. Never throttled, triggers preemption.
pub const REALTIME: Self = Self(0);
/// Functionality-blocking tasks. Throttled only under extreme load.
pub const HIGH: Self = Self(64);
/// Normal background operations. Yields to interactive work.
pub const NORMAL: Self = Self(128);
/// Low priority. Pauses under significant load.
pub const BACKGROUND: Self = Self(192);
/// Idle-only work. Runs only when system is otherwise idle.
pub const IDLE: Self = Self(255);
/// Construct a priority from a raw value. 0 = highest, 255 = lowest.
pub const fn new(level: u8) -> Self {
Self(level)
}
/// Raw numeric value.
pub const fn value(self) -> u8 {
self.0
}
}
/// Ordering: lower numeric value = higher priority = compares as Greater.
/// This makes `BinaryHeap` (max-heap) pop the highest-priority item first.
impl Ord for Priority {
fn cmp(&self, other: &Self) -> Ordering {
// Reverse: lower value is "greater" (higher priority).
other.0.cmp(&self.0)
}
}
impl PartialOrd for Priority {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl fmt::Debug for Priority {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let label = match self.0 {
0 => "REALTIME",
64 => "HIGH",
128 => "NORMAL",
192 => "BACKGROUND",
255 => "IDLE",
_ => return write!(f, "Priority({})", self.0),
};
write!(f, "Priority::{label}")
}
}
impl fmt::Display for Priority {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl From<u8> for Priority {
fn from(v: u8) -> Self {
Self(v)
}
}
impl From<Priority> for u8 {
fn from(p: Priority) -> Self {
p.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn realtime_is_highest() {
assert!(Priority::REALTIME > Priority::HIGH);
assert!(Priority::HIGH > Priority::NORMAL);
assert!(Priority::NORMAL > Priority::BACKGROUND);
assert!(Priority::BACKGROUND > Priority::IDLE);
}
#[test]
fn custom_priorities_between_tiers() {
let p = Priority::new(96);
assert!(p < Priority::HIGH); // lower priority than HIGH
assert!(p > Priority::NORMAL); // higher priority than NORMAL
}
#[test]
fn debug_named_tiers() {
assert_eq!(format!("{:?}", Priority::REALTIME), "Priority::REALTIME");
assert_eq!(format!("{:?}", Priority::new(42)), "Priority(42)");
}
}