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