xref: /DragonOS/kernel/src/libs/semaphore.rs (revision 2b7818e80e00fcfe4d03533f587cc125ea5e4bec)
1 use core::sync::atomic::{AtomicI32, Ordering};
2 
3 use log::debug;
4 use system_error::SystemError;
5 
6 use crate::process::ProcessManager;
7 
8 use super::wait_queue::WaitQueue;
9 
10 /// @brief 信号量的结构体
11 #[derive(Debug)]
12 struct Semaphore {
13     counter: AtomicI32,
14     wait_queue: WaitQueue,
15 }
16 
17 impl Semaphore {
18     #[allow(dead_code)]
19     #[inline]
20     /// @brief 初始化信号量
21     ///
22     /// @param count 信号量的初始值
23     /// @return 条件满足返回semaphore对象,条件不满足返回err信息
24     fn new(counter: i32) -> Result<Self, SystemError> {
25         if counter > 0 {
26             Ok(Self {
27                 counter: AtomicI32::new(counter),
28                 wait_queue: WaitQueue::default(),
29             })
30         } else {
31             return Err(SystemError::EOVERFLOW);
32         }
33     }
34 
35     #[allow(dead_code)]
36     #[inline]
37     fn down(&self) {
38         if self.counter.fetch_sub(1, Ordering::Release) <= 0 {
39             self.counter.fetch_add(1, Ordering::Relaxed);
40             self.wait_queue.sleep();
41             //资源不充足,信号量<=0, 此时进程睡眠
42         }
43     }
44 
45     #[allow(dead_code)]
46     #[inline]
47     fn up(&self) {
48         // 判断有没有进程在等待资源
49         if self.wait_queue.len() > 0 {
50             self.counter.fetch_add(1, Ordering::Release);
51         } else {
52             //尝试唤醒
53             if !self.wait_queue.wakeup(None) {
54                 //如果唤醒失败,打印错误信息
55                 debug!(
56                     "Semaphore wakeup failed: current pid= {}, semaphore={:?}",
57                     ProcessManager::current_pcb().pid().into(),
58                     self
59                 );
60             }
61         }
62     }
63 }
64