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