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