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