agentic_robotics_rt/
scheduler.rs1use crate::RTPriority;
4use std::collections::BinaryHeap;
5use std::cmp::Ordering;
6use std::time::{Duration, Instant};
7
8#[derive(Debug)]
10pub struct ScheduledTask {
11 pub priority: RTPriority,
12 pub deadline: Instant,
13 pub task_id: u64,
14}
15
16impl PartialEq for ScheduledTask {
17 fn eq(&self, other: &Self) -> bool {
18 self.priority == other.priority && self.deadline == other.deadline
19 }
20}
21
22impl Eq for ScheduledTask {}
23
24impl PartialOrd for ScheduledTask {
25 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
26 Some(self.cmp(other))
27 }
28}
29
30impl Ord for ScheduledTask {
31 fn cmp(&self, other: &Self) -> Ordering {
32 match self.priority.cmp(&other.priority) {
34 Ordering::Equal => other.deadline.cmp(&self.deadline),
35 ordering => ordering,
36 }
37 }
38}
39
40pub struct PriorityScheduler {
42 queue: BinaryHeap<ScheduledTask>,
43 next_task_id: u64,
44}
45
46impl PriorityScheduler {
47 pub fn new() -> Self {
49 Self {
50 queue: BinaryHeap::new(),
51 next_task_id: 0,
52 }
53 }
54
55 pub fn schedule(&mut self, priority: RTPriority, deadline: Duration) -> u64 {
57 let task_id = self.next_task_id;
58 self.next_task_id += 1;
59
60 let task = ScheduledTask {
61 priority,
62 deadline: Instant::now() + deadline,
63 task_id,
64 };
65
66 self.queue.push(task);
67 task_id
68 }
69
70 pub fn next_task(&mut self) -> Option<ScheduledTask> {
72 self.queue.pop()
73 }
74
75 pub fn pending_tasks(&self) -> usize {
77 self.queue.len()
78 }
79
80 pub fn clear(&mut self) {
82 self.queue.clear();
83 }
84}
85
86impl Default for PriorityScheduler {
87 fn default() -> Self {
88 Self::new()
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95
96 #[test]
97 fn test_scheduler() {
98 let mut scheduler = PriorityScheduler::new();
99
100 scheduler.schedule(RTPriority::Low, Duration::from_millis(100));
102 scheduler.schedule(RTPriority::High, Duration::from_millis(100));
103 scheduler.schedule(RTPriority::Critical, Duration::from_millis(100));
104
105 assert_eq!(scheduler.pending_tasks(), 3);
106
107 let task1 = scheduler.next_task().unwrap();
109 assert_eq!(task1.priority, RTPriority::Critical);
110
111 let task2 = scheduler.next_task().unwrap();
113 assert_eq!(task2.priority, RTPriority::High);
114
115 let task3 = scheduler.next_task().unwrap();
117 assert_eq!(task3.priority, RTPriority::Low);
118
119 assert_eq!(scheduler.pending_tasks(), 0);
120 }
121}