Browse Source

新增了rust实现的信号量 (#183)

* 新增了rust实现的信号量
Gou Ngai 2 years ago
parent
commit
83b9512c1c
4 changed files with 63 additions and 3 deletions
  1. 1 0
      kernel/src/libs/mod.rs
  2. 60 0
      kernel/src/libs/semaphore.rs
  3. 1 1
      kernel/src/libs/wait_queue.rs
  4. 1 2
      kernel/src/sched/rt.rs

+ 1 - 0
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;

+ 60 - 0
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<Self, i32> {
+        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
+                );
+            }
+        }
+    }
+}

+ 1 - 1
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();
     }
 }

+ 1 - 2
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调度器类