1use core::ptr;
6
7use alloc::{collections::btree_map::BTreeMap, sync::Arc};
8
9use crate::{kernel::SharedTask, sync::SpinLock, vfs::TimeSpec};
10
11lazy_static::lazy_static! {
12 pub static ref TIMER_QUEUE: SpinLock<TimerQueue> = SpinLock::new(TimerQueue::new());
16 pub static ref TIMER: SpinLock<TimerEntries> = SpinLock::new(TimerEntries::new());
20}
21
22pub struct TimerQueue {
24 queue: BTreeMap<usize, SharedTask>,
26}
27
28impl TimerQueue {
29 pub fn new() -> Self {
31 Self {
32 queue: BTreeMap::new(),
33 }
34 }
35
36 pub fn push(&mut self, mut trigger_time: usize, task: SharedTask) {
41 while self.queue.contains_key(&trigger_time) {
42 trigger_time += 1;
43 }
44 self.queue.insert(trigger_time, task);
45 }
46
47 pub fn pop_due_task(&mut self, current_time: usize) -> Option<SharedTask> {
53 if let Some((&trigger_time, _)) = self.queue.iter().next() {
54 if trigger_time <= current_time {
55 return self.queue.remove(&trigger_time);
56 }
57 }
58 None
59 }
60
61 pub fn remove_task(&mut self, task: &SharedTask) -> Option<SharedTask> {
67 let key = self.queue.iter().find_map(|(time, t)| {
68 if Arc::ptr_eq(task, t) {
69 Some(*time)
70 } else {
71 None
72 }
73 })?;
74 self.queue.remove(&key)
75 }
76}
77
78pub struct TimerEntry {
80 pub sig: usize,
82 pub task: SharedTask,
84 pub it_interval: TimeSpec,
86}
87
88impl TimerEntry {
89 pub fn new(sig: usize, task: SharedTask, it_interval: TimeSpec) -> Self {
91 Self {
92 sig,
93 task,
94 it_interval,
95 }
96 }
97}
98
99pub struct TimerEntries {
101 pub entries: BTreeMap<usize, TimerEntry>,
102}
103
104impl TimerEntries {
105 pub fn new() -> Self {
107 Self {
108 entries: BTreeMap::new(),
109 }
110 }
111
112 pub fn push(&mut self, trigger_time: usize, entry: TimerEntry) {
117 self.entries.insert(trigger_time, entry);
118 }
119
120 pub fn pop_due_entry(&mut self, current_time: usize) -> Option<TimerEntry> {
126 if let Some((&trigger_time, _)) = self.entries.iter().next() {
127 if trigger_time <= current_time {
128 return self.entries.remove(&trigger_time);
129 }
130 }
131 None
132 }
133
134 pub fn find_entry(&self, task: &SharedTask, sig: usize) -> Option<(&usize, &TimerEntry)> {
140 for (time, entry) in self.entries.iter() {
141 if ptr::eq(task, &entry.task) && entry.sig == sig {
142 return Some((time, entry));
143 }
144 }
145 None
146 }
147
148 pub fn remove_entry(&mut self, task: &SharedTask, sig: usize) -> Option<TimerEntry> {
154 let key = self.find_entry(task, sig).map(|(time, _)| *time)?;
155 self.entries.remove(&key)
156 }
157}