diff --git a/kernel/src/libs/mod.rs b/kernel/src/libs/mod.rs index 121d9aa4..bbf27b7b 100644 --- a/kernel/src/libs/mod.rs +++ b/kernel/src/libs/mod.rs @@ -7,4 +7,5 @@ pub mod atomic; pub mod list; pub mod lockref; pub mod mutex; +pub mod semaphore; pub mod wait_queue; diff --git a/kernel/src/libs/semaphore.rs b/kernel/src/libs/semaphore.rs new file mode 100644 index 00000000..72def321 --- /dev/null +++ b/kernel/src/libs/semaphore.rs @@ -0,0 +1,60 @@ +use core::sync::atomic::{AtomicI32, Ordering}; + +use crate::{arch::asm::current::current_pcb, include::bindings::bindings::EOVERFLOW, kdebug}; + +use super::wait_queue::WaitQueue; + +/// @brief 信号量的结构体 +#[derive(Debug)] +struct Semaphore { + counter: AtomicI32, + wait_queue: WaitQueue, +} + +impl Semaphore { + #[allow(dead_code)] + #[inline] + /// @brief 初始化信号量 + /// + /// @param count 信号量的初始值 + /// @return 条件满足返回semaphore对象,条件不满足返回err信息 + fn new(counter: i32) -> Result { + if counter > 0 { + Ok(Self { + counter: AtomicI32::new(counter), + wait_queue: WaitQueue::INIT, + }) + } else { + return Err(-(EOVERFLOW as i32)); + } + } + + #[allow(dead_code)] + #[inline] + fn down(&self) { + if self.counter.fetch_sub(1, Ordering::Release) <= 0 { + self.counter.fetch_add(1, Ordering::Relaxed); + self.wait_queue.sleep(); + //资源不充足,信号量<=0, 此时进程睡眠 + } + } + + #[allow(dead_code)] + #[inline] + fn up(&self) { + // 判断有没有进程在等待资源 + if self.wait_queue.len() > 0 { + self.counter.fetch_add(1, Ordering::Release); + } else { + //尝试唤醒 + if !self.wait_queue.wakeup(0x_ffff_ffff_ffff_ffff) { + //如果唤醒失败,打印错误信息 + kdebug!( + "Semaphore wakeup failed: current pid= {}, semaphore={:?}", + current_pcb().pid, + self + ); + } + } + } +} diff --git a/kernel/src/libs/wait_queue.rs b/kernel/src/libs/wait_queue.rs index c1e6c339..610732a7 100644 --- a/kernel/src/libs/wait_queue.rs +++ b/kernel/src/libs/wait_queue.rs @@ -128,7 +128,7 @@ impl WaitQueue { } /// @brief 获得当前等待队列的大小 - pub fn len(&self)->usize{ + pub fn len(&self) -> usize { return self.0.lock().wait_list.len(); } } diff --git a/kernel/src/sched/rt.rs b/kernel/src/sched/rt.rs index 14917393..070ec4a6 100644 --- a/kernel/src/sched/rt.rs +++ b/kernel/src/sched/rt.rs @@ -1,6 +1,6 @@ use core::{ptr::null_mut, sync::atomic::compiler_fence}; -use alloc::{boxed::Box, vec::Vec, collections::LinkedList}; +use alloc::{boxed::Box, collections::LinkedList, vec::Vec}; use crate::{ arch::asm::current::current_pcb, @@ -86,7 +86,6 @@ impl RTQueue { self.queue.push_front(pcb); self.lock.unlock(); } - } /// @brief RT调度器类