xref: /DragonOS/kernel/src/libs/notifier.rs (revision 729a96ef47f473d535d8317a2ace5ba141fd282a)
1*729a96efSXshine use crate::{
2*729a96efSXshine     kwarn,
3*729a96efSXshine     libs::{rwlock::RwLock, spinlock::SpinLock},
4*729a96efSXshine     syscall::SystemError,
5*729a96efSXshine };
6*729a96efSXshine use alloc::{sync::Arc, vec::Vec};
7*729a96efSXshine 
8*729a96efSXshine /// @brief 通知链节点
9*729a96efSXshine pub trait NotifierBlock<T> {
10*729a96efSXshine     /// @brief 通知链中注册的回调函数类型
11*729a96efSXshine     fn notifier_call(&self, action: u64, data: Option<&T>) -> i32;
12*729a96efSXshine     /// @brief 通知链节点的优先级
13*729a96efSXshine     fn priority(&self) -> i32;
14*729a96efSXshine }
15*729a96efSXshine 
16*729a96efSXshine /// @brief 通知链
17*729a96efSXshine // TODO: 考虑使用红黑树封装
18*729a96efSXshine struct NotifierChain<T>(Vec<Arc<dyn NotifierBlock<T>>>);
19*729a96efSXshine 
20*729a96efSXshine impl<T> NotifierChain<T> {
21*729a96efSXshine     pub fn new() -> Self {
22*729a96efSXshine         Self(vec![])
23*729a96efSXshine     }
24*729a96efSXshine 
25*729a96efSXshine     /// @brief 将节点注册到通知链
26*729a96efSXshine     /// @param unique_priority 检查通知链中优先级的唯一性
27*729a96efSXshine     pub fn register(
28*729a96efSXshine         &mut self,
29*729a96efSXshine         block: Arc<dyn NotifierBlock<T>>,
30*729a96efSXshine         unique_priority: bool,
31*729a96efSXshine     ) -> Result<(), SystemError> {
32*729a96efSXshine         let mut index: usize = 0;
33*729a96efSXshine 
34*729a96efSXshine         // 在 notifier chain中寻找第一个优先级比要插入块低的块
35*729a96efSXshine         for b in self.0.iter() {
36*729a96efSXshine             // 判断之前是否已经注册过该节点
37*729a96efSXshine             if Arc::as_ptr(&block) == Arc::as_ptr(b) {
38*729a96efSXshine                 kwarn!(
39*729a96efSXshine                     "notifier callback {:?} already registered",
40*729a96efSXshine                     Arc::as_ptr(&block)
41*729a96efSXshine                 );
42*729a96efSXshine                 return Err(SystemError::EEXIST);
43*729a96efSXshine             }
44*729a96efSXshine 
45*729a96efSXshine             if block.priority() > b.priority() {
46*729a96efSXshine                 break;
47*729a96efSXshine             }
48*729a96efSXshine 
49*729a96efSXshine             // 优先级唯一性检测
50*729a96efSXshine             if block.priority() == b.priority() && unique_priority {
51*729a96efSXshine                 return Err(SystemError::EBUSY);
52*729a96efSXshine             }
53*729a96efSXshine 
54*729a96efSXshine             index += 1;
55*729a96efSXshine         }
56*729a96efSXshine 
57*729a96efSXshine         // 插入 notifier chain
58*729a96efSXshine         self.0.insert(index, block);
59*729a96efSXshine         return Ok(());
60*729a96efSXshine     }
61*729a96efSXshine 
62*729a96efSXshine     /// @brief 在通知链中取消注册节点
63*729a96efSXshine     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<T>>) -> Result<(), SystemError> {
64*729a96efSXshine         let remove = self
65*729a96efSXshine             .0
66*729a96efSXshine             .drain_filter(|b| Arc::as_ptr(&block) == Arc::as_ptr(b));
67*729a96efSXshine         match remove.count() {
68*729a96efSXshine             0 => return Err(SystemError::ENOENT),
69*729a96efSXshine             _ => return Ok(()),
70*729a96efSXshine         }
71*729a96efSXshine     }
72*729a96efSXshine 
73*729a96efSXshine     /// @brief 通知链进行事件通知
74*729a96efSXshine     /// @param nr_to_call 回调函数次数
75*729a96efSXshine     /// @return (最后一次回调函数的返回值,回调次数)
76*729a96efSXshine     // TODO: 增加 NOTIFIER_STOP_MASK 相关功能
77*729a96efSXshine     pub fn call_chain(
78*729a96efSXshine         &self,
79*729a96efSXshine         action: u64,
80*729a96efSXshine         data: Option<&T>,
81*729a96efSXshine         nr_to_call: Option<usize>,
82*729a96efSXshine     ) -> (i32, usize) {
83*729a96efSXshine         let mut ret: i32 = 0;
84*729a96efSXshine         let mut nr_calls: usize = 0;
85*729a96efSXshine 
86*729a96efSXshine         for b in self.0.iter() {
87*729a96efSXshine             if nr_to_call.is_some_and(|x| nr_calls >= x) {
88*729a96efSXshine                 break;
89*729a96efSXshine             }
90*729a96efSXshine             ret = b.notifier_call(action, data);
91*729a96efSXshine             nr_calls += 1;
92*729a96efSXshine         }
93*729a96efSXshine         return (ret, nr_calls);
94*729a96efSXshine     }
95*729a96efSXshine }
96*729a96efSXshine 
97*729a96efSXshine /// @brief 原子的通知链,使用 SpinLock 进行同步
98*729a96efSXshine pub struct AtomicNotifierChain<T>(SpinLock<NotifierChain<T>>);
99*729a96efSXshine 
100*729a96efSXshine impl<T> AtomicNotifierChain<T> {
101*729a96efSXshine     pub fn new() -> Self {
102*729a96efSXshine         Self(SpinLock::new(NotifierChain::<T>::new()))
103*729a96efSXshine     }
104*729a96efSXshine 
105*729a96efSXshine     pub fn register(&mut self, block: Arc<dyn NotifierBlock<T>>) -> Result<(), SystemError> {
106*729a96efSXshine         let mut notifier_chain_guard = self.0.lock();
107*729a96efSXshine         return notifier_chain_guard.register(block, false);
108*729a96efSXshine     }
109*729a96efSXshine 
110*729a96efSXshine     pub fn register_unique_prio(
111*729a96efSXshine         &mut self,
112*729a96efSXshine         block: Arc<dyn NotifierBlock<T>>,
113*729a96efSXshine     ) -> Result<(), SystemError> {
114*729a96efSXshine         let mut notifier_chain_guard = self.0.lock();
115*729a96efSXshine         return notifier_chain_guard.register(block, true);
116*729a96efSXshine     }
117*729a96efSXshine 
118*729a96efSXshine     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<T>>) -> Result<(), SystemError> {
119*729a96efSXshine         let mut notifier_chain_guard = self.0.lock();
120*729a96efSXshine         return notifier_chain_guard.unregister(block);
121*729a96efSXshine     }
122*729a96efSXshine 
123*729a96efSXshine     pub fn call_chain(
124*729a96efSXshine         &self,
125*729a96efSXshine         action: u64,
126*729a96efSXshine         data: Option<&T>,
127*729a96efSXshine         nr_to_call: Option<usize>,
128*729a96efSXshine     ) -> (i32, usize) {
129*729a96efSXshine         let notifier_chain_guard = self.0.lock();
130*729a96efSXshine         return notifier_chain_guard.call_chain(action, data, nr_to_call);
131*729a96efSXshine     }
132*729a96efSXshine }
133*729a96efSXshine 
134*729a96efSXshine /// @brief 可阻塞的通知链,使用 RwLock 进行同步
135*729a96efSXshine // TODO: 使用 semaphore 封装
136*729a96efSXshine pub struct BlockingNotifierChain<T>(RwLock<NotifierChain<T>>);
137*729a96efSXshine 
138*729a96efSXshine impl<T> BlockingNotifierChain<T> {
139*729a96efSXshine     pub fn new() -> Self {
140*729a96efSXshine         Self(RwLock::new(NotifierChain::<T>::new()))
141*729a96efSXshine     }
142*729a96efSXshine 
143*729a96efSXshine     pub fn register(&mut self, block: Arc<dyn NotifierBlock<T>>) -> Result<(), SystemError> {
144*729a96efSXshine         let mut notifier_chain_guard = self.0.write();
145*729a96efSXshine         return notifier_chain_guard.register(block, false);
146*729a96efSXshine     }
147*729a96efSXshine 
148*729a96efSXshine     pub fn register_unique_prio(
149*729a96efSXshine         &mut self,
150*729a96efSXshine         block: Arc<dyn NotifierBlock<T>>,
151*729a96efSXshine     ) -> Result<(), SystemError> {
152*729a96efSXshine         let mut notifier_chain_guard = self.0.write();
153*729a96efSXshine         return notifier_chain_guard.register(block, true);
154*729a96efSXshine     }
155*729a96efSXshine 
156*729a96efSXshine     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<T>>) -> Result<(), SystemError> {
157*729a96efSXshine         let mut notifier_chain_guard = self.0.write();
158*729a96efSXshine         return notifier_chain_guard.unregister(block);
159*729a96efSXshine     }
160*729a96efSXshine 
161*729a96efSXshine     pub fn call_chain(
162*729a96efSXshine         &self,
163*729a96efSXshine         action: u64,
164*729a96efSXshine         data: Option<&T>,
165*729a96efSXshine         nr_to_call: Option<usize>,
166*729a96efSXshine     ) -> (i32, usize) {
167*729a96efSXshine         let notifier_chain_guard = self.0.read();
168*729a96efSXshine         return notifier_chain_guard.call_chain(action, data, nr_to_call);
169*729a96efSXshine     }
170*729a96efSXshine }
171*729a96efSXshine 
172*729a96efSXshine /// @brief 原始的通知链,由调用者自行考虑同步
173*729a96efSXshine pub struct RawNotifierChain<T>(NotifierChain<T>);
174*729a96efSXshine 
175*729a96efSXshine impl<T> RawNotifierChain<T> {
176*729a96efSXshine     pub fn new() -> Self {
177*729a96efSXshine         Self(NotifierChain::<T>::new())
178*729a96efSXshine     }
179*729a96efSXshine 
180*729a96efSXshine     pub fn register(&mut self, block: Arc<dyn NotifierBlock<T>>) -> Result<(), SystemError> {
181*729a96efSXshine         return self.0.register(block, false);
182*729a96efSXshine     }
183*729a96efSXshine 
184*729a96efSXshine     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<T>>) -> Result<(), SystemError> {
185*729a96efSXshine         return self.0.unregister(block);
186*729a96efSXshine     }
187*729a96efSXshine 
188*729a96efSXshine     pub fn call_chain(
189*729a96efSXshine         &self,
190*729a96efSXshine         action: u64,
191*729a96efSXshine         data: Option<&T>,
192*729a96efSXshine         nr_to_call: Option<usize>,
193*729a96efSXshine     ) -> (i32, usize) {
194*729a96efSXshine         return self.0.call_chain(action, data, nr_to_call);
195*729a96efSXshine     }
196*729a96efSXshine }
197