xref: /DragonOS/kernel/src/libs/semaphore.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
183b9512cSGou Ngai use core::sync::atomic::{AtomicI32, Ordering};
283b9512cSGou Ngai 
3*2eab6dd7S曾俊 use log::debug;
491e9d4abSLoGin use system_error::SystemError;
591e9d4abSLoGin 
6*2eab6dd7S曾俊 use crate::process::ProcessManager;
783b9512cSGou Ngai 
883b9512cSGou Ngai use super::wait_queue::WaitQueue;
983b9512cSGou Ngai 
1083b9512cSGou Ngai /// @brief 信号量的结构体
1183b9512cSGou Ngai #[derive(Debug)]
1283b9512cSGou Ngai struct Semaphore {
1383b9512cSGou Ngai     counter: AtomicI32,
1483b9512cSGou Ngai     wait_queue: WaitQueue,
1583b9512cSGou Ngai }
1683b9512cSGou Ngai 
1783b9512cSGou Ngai impl Semaphore {
1883b9512cSGou Ngai     #[allow(dead_code)]
1983b9512cSGou Ngai     #[inline]
2083b9512cSGou Ngai     /// @brief 初始化信号量
2183b9512cSGou Ngai     ///
2283b9512cSGou Ngai     /// @param count 信号量的初始值
2383b9512cSGou Ngai     /// @return 条件满足返回semaphore对象,条件不满足返回err信息
new(counter: i32) -> Result<Self, SystemError>24676b8ef6SMork     fn new(counter: i32) -> Result<Self, SystemError> {
2583b9512cSGou Ngai         if counter > 0 {
2683b9512cSGou Ngai             Ok(Self {
2783b9512cSGou Ngai                 counter: AtomicI32::new(counter),
28b5b571e0SLoGin                 wait_queue: WaitQueue::default(),
2983b9512cSGou Ngai             })
3083b9512cSGou Ngai         } else {
31676b8ef6SMork             return Err(SystemError::EOVERFLOW);
3283b9512cSGou Ngai         }
3383b9512cSGou Ngai     }
3483b9512cSGou Ngai 
3583b9512cSGou Ngai     #[allow(dead_code)]
3683b9512cSGou Ngai     #[inline]
down(&self)3783b9512cSGou Ngai     fn down(&self) {
3883b9512cSGou Ngai         if self.counter.fetch_sub(1, Ordering::Release) <= 0 {
3983b9512cSGou Ngai             self.counter.fetch_add(1, Ordering::Relaxed);
4083b9512cSGou Ngai             self.wait_queue.sleep();
4183b9512cSGou Ngai             //资源不充足,信号量<=0, 此时进程睡眠
4283b9512cSGou Ngai         }
4383b9512cSGou Ngai     }
4483b9512cSGou Ngai 
4583b9512cSGou Ngai     #[allow(dead_code)]
4683b9512cSGou Ngai     #[inline]
up(&self)4783b9512cSGou Ngai     fn up(&self) {
4883b9512cSGou Ngai         // 判断有没有进程在等待资源
4983b9512cSGou Ngai         if self.wait_queue.len() > 0 {
5083b9512cSGou Ngai             self.counter.fetch_add(1, Ordering::Release);
5183b9512cSGou Ngai         } else {
5283b9512cSGou Ngai             //尝试唤醒
531496ba7bSLoGin             if !self.wait_queue.wakeup(None) {
5483b9512cSGou Ngai                 //如果唤醒失败,打印错误信息
55*2eab6dd7S曾俊                 debug!(
5683b9512cSGou Ngai                     "Semaphore wakeup failed: current pid= {}, semaphore={:?}",
571496ba7bSLoGin                     ProcessManager::current_pcb().pid().into(),
5883b9512cSGou Ngai                     self
5983b9512cSGou Ngai                 );
6083b9512cSGou Ngai             }
6183b9512cSGou Ngai         }
6283b9512cSGou Ngai     }
6383b9512cSGou Ngai }
64