Przeglądaj źródła

Patch sched rust (#139)

* update

* 添加rt调度器的rust初步实现

* 完善rt调度逻辑

* 调试rt调度器

* 修改sched的返回值

* cargo fmt 格式化

* 删除无用代码,修补rt bug

* 删除无用的代码,和重复的逻辑

* 软中断bugfix

* 删除一些代码

* 添加kthread_run_rt文档

* 解决sphinix警告_static目录不存在的问题

Co-authored-by: longjin <[email protected]>
kong 2 lat temu
rodzic
commit
06b09f34ed
44 zmienionych plików z 425 dodań i 172 usunięć
  1. 0 0
      docs/_static/.gitkeep
  2. 12 0
      docs/kernel/process_management/kthread.md
  3. 1 1
      kernel/src/arch/x86_64/asm/bitops.rs
  4. 2 2
      kernel/src/arch/x86_64/asm/mod.rs
  5. 4 4
      kernel/src/arch/x86_64/asm/ptrace.rs
  6. 5 5
      kernel/src/arch/x86_64/interrupt/mod.rs
  7. 7 7
      kernel/src/arch/x86_64/mm/barrier.rs
  8. 1 1
      kernel/src/arch/x86_64/mm/mod.rs
  9. 2 2
      kernel/src/arch/x86_64/mod.rs
  10. 17 0
      kernel/src/common/kthread.h
  11. 1 1
      kernel/src/driver/mod.rs
  12. 1 1
      kernel/src/driver/timers/mod.rs
  13. 1 1
      kernel/src/driver/timers/rtc/mod.rs
  14. 32 27
      kernel/src/driver/uart/uart.rs
  15. 1 3
      kernel/src/exception/softirq.h
  16. 2 2
      kernel/src/exception/softirq.rs
  17. 1 0
      kernel/src/filesystem/devfs/mod.rs
  18. 1 0
      kernel/src/filesystem/fat32/mod.rs
  19. 1 0
      kernel/src/filesystem/procfs/mod.rs
  20. 1 0
      kernel/src/filesystem/rootfs/mod.rs
  21. 1 0
      kernel/src/filesystem/vfs/mod.rs
  22. 1 1
      kernel/src/include/bindings/mod.rs
  23. 1 1
      kernel/src/include/mod.rs
  24. 1 1
      kernel/src/ipc/mod.rs
  25. 1 1
      kernel/src/ipc/signal_types.rs
  26. 2 2
      kernel/src/libs/atomic.rs
  27. 4 18
      kernel/src/libs/ffi_convert.rs
  28. 9 6
      kernel/src/libs/list.rs
  29. 22 22
      kernel/src/libs/lockref.rs
  30. 3 3
      kernel/src/libs/mod.rs
  31. 18 12
      kernel/src/libs/refcount.rs
  32. 8 6
      kernel/src/libs/wait_queue.rs
  33. 1 1
      kernel/src/mm/allocator.rs
  34. 1 2
      kernel/src/process/initial_proc.rs
  35. 3 3
      kernel/src/process/mod.rs
  36. 3 3
      kernel/src/process/pid.rs
  37. 1 0
      kernel/src/process/proc-types.h
  38. 23 1
      kernel/src/process/process.c
  39. 1 3
      kernel/src/process/process.rs
  40. 9 19
      kernel/src/sched/cfs.rs
  41. 43 8
      kernel/src/sched/core.rs
  42. 2 1
      kernel/src/sched/mod.rs
  43. 173 0
      kernel/src/sched/rt.rs
  44. 1 1
      kernel/src/smp/mod.rs

+ 0 - 0
docs/_static/.gitkeep


+ 12 - 0
docs/kernel/process_management/kthread.md

@@ -62,6 +62,18 @@
 
 &emsp;&emsp;该宏定义是`kthread_create()`的简单封装,提供创建了内核线程后,立即运行的功能。
 
+### kthread_run_rt()
+
+#### 原型
+
+&emsp;&emsp;`kthread_run_rt(thread_fn, data, name_fmt, ...)`
+
+#### 简介
+
+&emsp;&emsp;创建内核实时线程并加入调度队列。
+
+&emsp;&emsp;类似`kthread_run()`,该宏定义也是`kthread_create()`的简单封装,提供创建了内核实时线程后,在设置实时进程的参数后,立即运行的功能。
+
 ## 停止内核线程
 
 ### kthread_stop()

+ 1 - 1
kernel/src/arch/x86_64/asm/bitops.rs

@@ -2,7 +2,7 @@ use core::arch::x86_64::_popcnt64;
 
 /// @brief ffz - 寻找u64中的第一个0所在的位(从第0位开始寻找)
 /// 请注意,如果x中没有0,那么结果将是未定义的。请确保传入的x至少存在1个0
-/// 
+///
 /// @param x 目标u64
 /// @return i32 bit-number(0..63) of the first (least significant) zero bit.
 #[inline]

+ 2 - 2
kernel/src/arch/x86_64/asm/mod.rs

@@ -1,6 +1,6 @@
 pub mod irqflags;
 #[macro_use]
 pub mod current;
-pub mod ptrace;
 pub mod bitops;
-pub mod cmpxchg;
+pub mod cmpxchg;
+pub mod ptrace;

+ 4 - 4
kernel/src/arch/x86_64/asm/ptrace.rs

@@ -3,10 +3,10 @@ use crate::include::bindings::bindings::pt_regs;
 
 /// @brief 判断给定的栈帧是否来自用户态
 /// 判断方法为:根据代码段选择子是否具有ring3的访问权限(低2bit均为1)
-pub fn user_mode(regs: *const pt_regs)->bool{
-    if (unsafe{(*regs).cs} & 0x3) != 0{
+pub fn user_mode(regs: *const pt_regs) -> bool {
+    if (unsafe { (*regs).cs } & 0x3) != 0 {
         return true;
-    }else {
+    } else {
         return false;
     }
-}
+}

+ 5 - 5
kernel/src/arch/x86_64/interrupt/mod.rs

@@ -3,16 +3,16 @@ use core::arch::asm;
 
 /// @brief 关闭中断
 #[inline]
-pub fn cli(){
-    unsafe{
+pub fn cli() {
+    unsafe {
         asm!("cli");
     }
 }
 
 /// @brief 开启中断
 #[inline]
-pub fn sti(){
-    unsafe{
+pub fn sti() {
+    unsafe {
         asm!("sti");
     }
-}
+}

+ 7 - 7
kernel/src/arch/x86_64/mm/barrier.rs

@@ -2,22 +2,22 @@
 use core::arch::asm;
 
 #[inline(always)]
-pub fn mfence(){
-    unsafe{
+pub fn mfence() {
+    unsafe {
         asm!("mfence");
     }
 }
 
 #[inline(always)]
-pub fn lfence(){
-    unsafe{
+pub fn lfence() {
+    unsafe {
         asm!("lfence");
     }
 }
 
 #[inline(always)]
-pub fn sfence(){
-    unsafe{
+pub fn sfence() {
+    unsafe {
         asm!("sfence");
     }
-}
+}

+ 1 - 1
kernel/src/arch/x86_64/mm/mod.rs

@@ -19,7 +19,7 @@ pub fn switch_mm(
     mfence();
     // kdebug!("to get pml4t");
     let pml4t = unsafe { read_volatile(&next_pcb.mm.as_ref().unwrap().pgd) };
-    
+
     unsafe {
         asm!("mov cr3, {}", in(reg) pml4t);
     }

+ 2 - 2
kernel/src/arch/x86_64/mod.rs

@@ -1,7 +1,7 @@
 #[macro_use]
 pub mod asm;
+pub mod context;
 pub mod cpu;
 pub mod interrupt;
 pub mod mm;
-pub mod context;
-pub mod sched;
+pub mod sched;

+ 17 - 0
kernel/src/common/kthread.h

@@ -54,6 +54,23 @@ struct process_control_block *kthread_create_on_node(int (*thread_fn)(void *data
         __kt;                                                                                                \
     })
 
+/**
+ * @brief 创建内核实时线程,并将其唤醒
+ * 
+ * @param thread_fn 该内核线程要执行的函数
+ * @param data 传递给 thread_fn 的参数数据
+ * @param name_fmt printf-style format string for the thread name
+ * @param arg name_fmt的参数
+ */
+#define kthread_run_rt(thread_fn, data, name_fmt, ...)                                                          \
+    ({                                                                                                       \
+        struct process_control_block *__kt = kthread_create(thread_fn, data, name_fmt, ##__VA_ARGS__); \
+        __kt=process_init_rt_pcb(__kt);                                                              \
+        if (!IS_ERR(__kt)){                                                                                   \
+            process_wakeup(__kt);}                                                                            \
+        __kt;                                                                                                \
+    })
+
 /**
  * @brief 向kthread发送停止信号,请求其结束
  * 

+ 1 - 1
kernel/src/driver/mod.rs

@@ -1,2 +1,2 @@
-pub mod uart;
 pub mod timers;
+pub mod uart;

+ 1 - 1
kernel/src/driver/timers/mod.rs

@@ -1 +1 @@
-pub mod rtc;
+pub mod rtc;

+ 1 - 1
kernel/src/driver/timers/rtc/mod.rs

@@ -1 +1 @@
-pub mod rtc;
+pub mod rtc;

+ 32 - 27
kernel/src/driver/uart/uart.rs

@@ -1,5 +1,5 @@
 use crate::include::bindings::bindings::{io_in8, io_out8};
-use core::{str, char, intrinsics::offset};
+use core::{char, intrinsics::offset, str};
 
 const UART_SUCCESS: i32 = 0;
 const E_UART_BITS_RATE_ERROR: i32 = 1;
@@ -63,7 +63,7 @@ impl UartPort {
 struct UartRegister {
     reg_data: u8,
     reg_interrupt_enable: u8,
-    reg_ii_fifo: u8,    // 	Interrupt Identification and FIFO control registers
+    reg_ii_fifo: u8, // 	Interrupt Identification and FIFO control registers
     reg_line_config: u8,
     reg_modem_config: u8,
     reg_line_status: u8,
@@ -79,7 +79,10 @@ pub struct UartDriver {
 
 impl Default for UartDriver {
     fn default() -> Self {
-        Self {port: UartPort::COM1, baud_rate: 115200}
+        Self {
+            port: UartPort::COM1,
+            baud_rate: 115200,
+        }
     }
 }
 
@@ -96,26 +99,26 @@ impl UartDriver {
         if baud_rate > UART_MAX_BITS_RATE || UART_MAX_BITS_RATE % baud_rate != 0 {
             return Err("uart init error.");
         }
-    
+
         unsafe {
             io_out8(port + 1, 0x00); // Disable all interrupts
             io_out8(port + 3, 0x80); // Enable DLAB (set baud rate divisor)
-        
+
             let divisor = UART_MAX_BITS_RATE / baud_rate;
-            
-            io_out8(port + 0, (divisor & 0xff) as u8);        // Set divisor  (lo byte)
+
+            io_out8(port + 0, (divisor & 0xff) as u8); // Set divisor  (lo byte)
             io_out8(port + 1, ((divisor >> 8) & 0xff) as u8); //                  (hi byte)
-            io_out8(port + 3, 0x03);                  // 8 bits, no parity, one stop bit
-            io_out8(port + 2, 0xC7);                  // Enable FIFO, clear them, with 14-byte threshold
+            io_out8(port + 3, 0x03); // 8 bits, no parity, one stop bit
+            io_out8(port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
             io_out8(port + 4, 0x08); // IRQs enabled, RTS/DSR clear (现代计算机上一般都不需要hardware flow control,因此不需要置位RTS/DSR)
             io_out8(port + 4, 0x1E); // Set in loopback mode, test the serial chip
             io_out8(port + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
-        
+
             // Check if serial is faulty (i.e: not same byte as sent)
             if io_in8(port + 0) != 0xAE {
                 return Err("uart faulty");
             }
-        
+
             // If serial is not faulty set it in normal operation mode
             // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
             io_out8(port + 4, 0x08);
@@ -133,15 +136,15 @@ impl UartDriver {
     }
 
     fn serial_received(offset: u16) -> bool {
-        if unsafe{ io_in8(offset + 5) } & 1 != 0 {
+        if unsafe { io_in8(offset + 5) } & 1 != 0 {
             true
         } else {
             false
         }
     }
-    
+
     fn is_transmit_empty(offset: u16) -> bool {
-        if unsafe{ io_in8(offset + 5) } & 0x20 != 0 {
+        if unsafe { io_in8(offset + 5) } & 0x20 != 0 {
             true
         } else {
             false
@@ -157,11 +160,13 @@ impl UartDriver {
         let port = uart_port.to_u16();
         while UartDriver::is_transmit_empty(port) == false {
             for c in str.bytes() {
-                unsafe { io_out8(port, c); }
+                unsafe {
+                    io_out8(port, c);
+                }
             }
         } //TODO:pause
     }
-    
+
     /// @brief 串口接收一个字节
     /// @param uart_port 端口号
     /// @return 接收的字节
@@ -171,7 +176,6 @@ impl UartDriver {
         while UartDriver::serial_received(port) == false {} //TODO:pause
         unsafe { io_in8(port) as char }
     }
-
 }
 
 ///@brief 发送数据
@@ -180,7 +184,9 @@ impl UartDriver {
 #[no_mangle]
 pub extern "C" fn c_uart_send(port: u16, c: u8) {
     while UartDriver::is_transmit_empty(port) == false {} //TODO:pause
-    unsafe { io_out8(port, c); }
+    unsafe {
+        io_out8(port, c);
+    }
 }
 
 ///@brief 从uart接收数据
@@ -196,8 +202,7 @@ pub extern "C" fn c_uart_read(port: u16) -> u8 {
 ///@param port 串口端口
 ///@param str 字符串S
 #[no_mangle]
-pub extern "C" fn c_uart_send_str(port: u16, str: *const u8)
-{
+pub extern "C" fn c_uart_send_str(port: u16, str: *const u8) {
     unsafe {
         let mut i = 0;
         while *offset(str, i) != '\0' as u8 {
@@ -222,22 +227,22 @@ pub extern "C" fn c_uart_init(port: u16, baud_rate: u32) -> i32 {
     unsafe {
         io_out8(port + 1, 0x00); // Disable all interrupts
         io_out8(port + 3, 0x80); // Enable DLAB (set baud rate divisor)
-    
+
         let divisor = UART_MAX_BITS_RATE / baud_rate;
-        
-        io_out8(port + 0, (divisor & 0xff) as u8);        // Set divisor  (lo byte)
+
+        io_out8(port + 0, (divisor & 0xff) as u8); // Set divisor  (lo byte)
         io_out8(port + 1, ((divisor >> 8) & 0xff) as u8); //                  (hi byte)
-        io_out8(port + 3, 0x03);                  // 8 bits, no parity, one stop bit
-        io_out8(port + 2, 0xC7);                  // Enable FIFO, clear them, with 14-byte threshold
+        io_out8(port + 3, 0x03); // 8 bits, no parity, one stop bit
+        io_out8(port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
         io_out8(port + 4, 0x08); // IRQs enabled, RTS/DSR clear (现代计算机上一般都不需要hardware flow control,因此不需要置位RTS/DSR)
         io_out8(port + 4, 0x1E); // Set in loopback mode, test the serial chip
         io_out8(port + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
-    
+
         // Check if serial is faulty (i.e: not same byte as sent)
         if io_in8(port + 0) != 0xAE {
             return -E_UART_SERIAL_FAULT;
         }
-    
+
         // If serial is not faulty set it in normal operation mode
         // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
         io_out8(port + 4, 0x08);

+ 1 - 3
kernel/src/exception/softirq.h

@@ -14,11 +14,9 @@
 
 // ==================implementation with rust===================
 extern void softirq_init();
-extern void raise_softirq(uint64_t sirq_num);
+extern void raise_softirq(uint32_t sirq_num);
 extern int register_softirq(uint32_t irq_num, void (*action)(void *data), void *data);
 extern int unregister_softirq(uint32_t irq_num);
-extern void set_softirq_pending(uint64_t status);
-extern void clear_softirq_pending(uint32_t irq_num);
 extern void do_softirq();
 
 // for temporary

+ 2 - 2
kernel/src/exception/softirq.rs

@@ -66,9 +66,9 @@ pub fn __get_softirq_handler_mut() -> &'static mut Softirq {
 
 #[no_mangle]
 #[allow(dead_code)]
-pub extern "C" fn raise_softirq(sirq_num: u64) {
+pub extern "C" fn raise_softirq(sirq_num: u32) {
     let softirq_handler = __get_softirq_handler_mut();
-    softirq_handler.set_softirq_pending(1 << sirq_num);
+    softirq_handler.set_softirq_pending(sirq_num);
 }
 
 /// @brief 软中断注册函数

+ 1 - 0
kernel/src/filesystem/devfs/mod.rs

@@ -0,0 +1 @@
+

+ 1 - 0
kernel/src/filesystem/fat32/mod.rs

@@ -0,0 +1 @@
+

+ 1 - 0
kernel/src/filesystem/procfs/mod.rs

@@ -0,0 +1 @@
+

+ 1 - 0
kernel/src/filesystem/rootfs/mod.rs

@@ -0,0 +1 @@
+

+ 1 - 0
kernel/src/filesystem/vfs/mod.rs

@@ -0,0 +1 @@
+

+ 1 - 1
kernel/src/include/bindings/mod.rs

@@ -1 +1 @@
-pub mod bindings;
+pub mod bindings;

+ 1 - 1
kernel/src/include/mod.rs

@@ -1,2 +1,2 @@
 #![allow(non_snake_case)]
-pub mod bindings;
+pub mod bindings;

+ 1 - 1
kernel/src/ipc/mod.rs

@@ -1,2 +1,2 @@
 pub mod signal;
-pub mod signal_types;
+pub mod signal_types;

+ 1 - 1
kernel/src/ipc/signal_types.rs

@@ -546,7 +546,7 @@ impl SigQueue {
     }
 
     /// @brief 从C的void*指针转换为static生命周期的可变引用
-    pub fn from_c_void(p: *mut c_void) -> &'static mut SigQueue{
+    pub fn from_c_void(p: *mut c_void) -> &'static mut SigQueue {
         let sq = p as *mut SigQueue;
         let sq = unsafe { sq.as_mut::<'static>() }.unwrap();
         return sq;

+ 2 - 2
kernel/src/libs/atomic.rs

@@ -13,8 +13,8 @@ pub fn atomic_read(ato: *const atomic_t) -> i64 {
 
 /// @brief 原子的设置原子变量的值
 #[inline]
-pub fn atomic_set(ato: *mut atomic_t, value:i64) {
-    unsafe{
+pub fn atomic_set(ato: *mut atomic_t, value: i64) {
+    unsafe {
         write_volatile(&mut (*ato).value, value);
     }
 }

+ 4 - 18
kernel/src/libs/ffi_convert.rs

@@ -6,24 +6,10 @@ pub trait FFIBind2Rust<T> {
     fn convert_mut(src: *mut T) -> Option<&'static mut Self>;
 }
 
-
-
-pub fn __convert_mut<'a, S, D>(src:*mut S) ->Option<&'a mut D>{
-    return unsafe {
-        core::mem::transmute::<
-            *mut S,
-            *mut D,
-        >(src)
-        .as_mut()
-    };
+pub fn __convert_mut<'a, S, D>(src: *mut S) -> Option<&'a mut D> {
+    return unsafe { core::mem::transmute::<*mut S, *mut D>(src).as_mut() };
 }
 
-pub fn __convert_ref<'a, S, D>(src:*const S) ->Option<&'a D>{
-    return unsafe {
-        core::mem::transmute::<
-            *const S,
-            *const D,
-        >(src)
-        .as_ref()
-    };
+pub fn __convert_ref<'a, S, D>(src: *const S) -> Option<&'a D> {
+    return unsafe { core::mem::transmute::<*const S, *const D>(src).as_ref() };
 }

+ 9 - 6
kernel/src/libs/list.rs

@@ -3,13 +3,16 @@ use crate::include::bindings::bindings::List;
 /// @brief 初始化链表
 #[inline]
 pub fn list_init(list: *mut List) {
-    unsafe{*list}.prev = list;
-    unsafe{*list}.next = list;
+    unsafe { *list }.prev = list;
+    unsafe { *list }.next = list;
 }
 
-impl Default for List{
+impl Default for List {
     fn default() -> Self {
-       let x= Self { prev: 0 as *mut List, next: 0 as *mut List };
-       return x;
+        let x = Self {
+            prev: 0 as *mut List,
+            next: 0 as *mut List,
+        };
+        return x;
     }
-}
+}

+ 22 - 22
kernel/src/libs/lockref.rs

@@ -324,32 +324,32 @@ impl LockRef {
 }
 
 /*
- * 您可以使用以下代码测试lockref
+* 您可以使用以下代码测试lockref
 
-    let mut lockref = LockRef::new();
-    kdebug!("lockref={:?}", lockref);
-    lockref.inc();
-    assert_eq!(lockref.count, 1);
-    kdebug!("lockref={:?}", lockref);
-    assert!(lockref.dec().is_ok());
-    assert_eq!(lockref.count, 0);
+   let mut lockref = LockRef::new();
+   kdebug!("lockref={:?}", lockref);
+   lockref.inc();
+   assert_eq!(lockref.count, 1);
+   kdebug!("lockref={:?}", lockref);
+   assert!(lockref.dec().is_ok());
+   assert_eq!(lockref.count, 0);
 
-    assert!(lockref.dec().is_err());
-    assert_eq!(lockref.count, 0);
+   assert!(lockref.dec().is_err());
+   assert_eq!(lockref.count, 0);
 
-    lockref.inc();
-    assert_eq!(lockref.count, 1);
+   lockref.inc();
+   assert_eq!(lockref.count, 1);
 
-    assert!(lockref.dec_not_zero().is_err());
+   assert!(lockref.dec_not_zero().is_err());
 
-    lockref.inc();
-    assert_eq!(lockref.count, 2);
+   lockref.inc();
+   assert_eq!(lockref.count, 2);
 
-    assert!(lockref.dec_not_zero().is_ok());
+   assert!(lockref.dec_not_zero().is_ok());
 
-    lockref.mark_dead();
-    assert!(lockref.count < 0);
-    
-    assert!(lockref.inc_not_dead().is_err());
-    kdebug!("lockref={:?}", lockref);
- */
+   lockref.mark_dead();
+   assert!(lockref.count < 0);
+
+   assert!(lockref.inc_not_dead().is_err());
+   kdebug!("lockref={:?}", lockref);
+*/

+ 3 - 3
kernel/src/libs/mod.rs

@@ -1,9 +1,9 @@
+pub mod ffi_convert;
 pub mod printk;
 pub mod spinlock;
-pub mod ffi_convert;
 #[macro_use]
 pub mod refcount;
 pub mod atomic;
-pub mod wait_queue;
 pub mod list;
-pub mod lockref;
+pub mod lockref;
+pub mod wait_queue;

+ 18 - 12
kernel/src/libs/refcount.rs

@@ -1,20 +1,28 @@
-use crate::{include::bindings::bindings::{atomic_inc, atomic_t, atomic_dec}, kwarn};
+use crate::{
+    include::bindings::bindings::{atomic_dec, atomic_inc, atomic_t},
+    kwarn,
+};
 
-use super::{ffi_convert::{FFIBind2Rust, __convert_mut, __convert_ref}, atomic::atomic_read};
+use super::{
+    atomic::atomic_read,
+    ffi_convert::{FFIBind2Rust, __convert_mut, __convert_ref},
+};
 
 #[derive(Debug, Copy, Clone)]
 pub struct RefCount {
     pub refs: atomic_t,
 }
 
-impl Default for RefCount{
+impl Default for RefCount {
     fn default() -> Self {
-        Self { refs:  atomic_t { value: 1 }}
+        Self {
+            refs: atomic_t { value: 1 },
+        }
     }
 }
 
 /// @brief 将给定的来自bindgen的refcount_t解析为Rust的RefCount的引用
-impl FFIBind2Rust<crate::include::bindings::bindings::refcount_struct> for RefCount{
+impl FFIBind2Rust<crate::include::bindings::bindings::refcount_struct> for RefCount {
     fn convert_mut(
         src: *mut crate::include::bindings::bindings::refcount_struct,
     ) -> Option<&'static mut Self> {
@@ -23,7 +31,7 @@ impl FFIBind2Rust<crate::include::bindings::bindings::refcount_struct> for RefCo
     fn convert_ref(
         src: *const crate::include::bindings::bindings::refcount_struct,
     ) -> Option<&'static Self> {
-        return __convert_ref(src)
+        return __convert_ref(src);
     }
 }
 
@@ -40,10 +48,10 @@ macro_rules! REFCOUNT_INIT {
 #[allow(dead_code)]
 #[inline]
 pub fn refcount_inc(r: &mut RefCount) {
-    if atomic_read(&r.refs) == 0{
+    if atomic_read(&r.refs) == 0 {
         kwarn!("Refcount increased from 0, may be use-after free");
     }
-    
+
     unsafe {
         atomic_inc(&mut r.refs);
     }
@@ -52,10 +60,8 @@ pub fn refcount_inc(r: &mut RefCount) {
 /// @brief 引用计数自减1
 #[allow(dead_code)]
 #[inline]
-pub fn refcount_dec(r: &mut RefCount){
-    unsafe{
+pub fn refcount_dec(r: &mut RefCount) {
+    unsafe {
         atomic_dec(&mut r.refs);
     }
 }
-
-

+ 8 - 6
kernel/src/libs/wait_queue.rs

@@ -1,12 +1,14 @@
-use crate::include::bindings::bindings::{wait_queue_head_t};
+use crate::include::bindings::bindings::wait_queue_head_t;
 
-use super::{list::list_init};
+use super::list::list_init;
 
-
-impl Default for wait_queue_head_t{
+impl Default for wait_queue_head_t {
     fn default() -> Self {
-        let mut x = Self { wait_list: Default::default(), lock: Default::default() };
+        let mut x = Self {
+            wait_list: Default::default(),
+            lock: Default::default(),
+        };
         list_init(&mut x.wait_list);
         return x;
     }
-}
+}

+ 1 - 1
kernel/src/mm/allocator.rs

@@ -1,5 +1,5 @@
-use crate::include::bindings::bindings::{gfp_t, kfree, kmalloc, PAGE_2M_SIZE};
 use super::gfp::__GFP_ZERO;
+use crate::include::bindings::bindings::{gfp_t, kfree, kmalloc, PAGE_2M_SIZE};
 
 use core::alloc::{GlobalAlloc, Layout};
 

+ 1 - 2
kernel/src/process/initial_proc.rs

@@ -26,10 +26,9 @@ pub static mut INITIAL_SIGHAND: sighand_struct = sighand_struct {
 /// @brief 初始化pid=0的进程的信号相关的信息
 #[no_mangle]
 pub extern "C" fn initial_proc_init_signal(pcb: *mut process_control_block) {
-    
     // 所设置的pcb的pid一定为0
     assert_eq!(unsafe { (*pcb).pid }, 0);
-    
+
     // 设置init进程的sighand和signal
     unsafe {
         (*pcb).sighand = &mut INITIAL_SIGHAND as *mut sighand_struct as usize

+ 3 - 3
kernel/src/process/mod.rs

@@ -1,5 +1,5 @@
+pub mod fork;
+pub mod initial_proc;
 pub mod pid;
-pub mod process;
 pub mod preempt;
-pub mod initial_proc;
-pub mod fork;
+pub mod process;

+ 3 - 3
kernel/src/process/pid.rs

@@ -1,4 +1,4 @@
-use crate::{include::bindings::bindings::pt_regs, arch::asm::current::current_pcb};
+use crate::{arch::asm::current::current_pcb, include::bindings::bindings::pt_regs};
 
 #[allow(dead_code)]
 #[derive(Debug, Clone, Copy)]
@@ -23,6 +23,6 @@ impl PartialEq for PidType {
  * @brief 获取当前进程的pid
  */
 #[no_mangle]
-pub extern "C" fn sys_getpid(_regs: &pt_regs)->u64{
+pub extern "C" fn sys_getpid(_regs: &pt_regs) -> u64 {
     return current_pcb().pid as u64;
-}
+}

+ 1 - 0
kernel/src/process/proc-types.h

@@ -105,6 +105,7 @@ struct process_control_block
     long pid;
     long priority;           // 优先级
     int64_t virtual_runtime; // 虚拟运行时间
+    int64_t rt_time_slice;  // 由实时调度器管理的时间片
 
     // 进程拥有的文件描述符的指针数组
     // todo: 改用动态指针数组

+ 23 - 1
kernel/src/process/process.c

@@ -409,7 +409,7 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
 
     // 关闭之前的文件描述符
     process_exit_files(current_pcb);
-    
+
     process_open_stdio(current_pcb);
 
     // 清除进程的vfork标志位
@@ -469,6 +469,22 @@ exec_failed:;
 }
 #pragma GCC pop_options
 
+/**
+ * @brief 初始化实时进程rt_pcb
+ *
+ * @return 初始化后的进程
+ *
+ */
+struct process_control_block *process_init_rt_pcb(struct process_control_block *rt_pcb)
+{
+    // 暂时将实时进程的优先级设置为10
+    rt_pcb->priority = 10;
+    rt_pcb->policy = SCHED_RR;
+    rt_pcb->rt_time_slice = 80;
+    rt_pcb->virtual_runtime = 0x7fffffffffffffff;
+    return rt_pcb;
+}
+
 /**
  * @brief 内核init进程
  *
@@ -508,6 +524,12 @@ ul initial_kernel_thread(ul arg)
     //     waitpid(tpid[i], NULL, NULL);
     // kinfo("All test done.");
 
+    // 测试实时进程
+
+    // struct process_control_block *test_rt1 = kthread_run_rt(&test, NULL, "test rt");
+    // kdebug("process:rt test kthread is created!!!!");
+
+
     // 准备切换到用户态
     struct pt_regs *regs;
 

+ 1 - 3
kernel/src/process/process.rs

@@ -2,9 +2,7 @@ use core::ptr::{read_volatile, write_volatile};
 
 use crate::{
     arch::asm::current::current_pcb,
-    include::bindings::bindings::{
-        process_control_block, PROC_RUNNING, PROC_STOPPED,
-    },
+    include::bindings::bindings::{process_control_block, PROC_RUNNING, PROC_STOPPED},
     sched::core::{cpu_executing, sched_enqueue},
     smp::core::{smp_get_processor_id, smp_send_reschedule},
 };

+ 9 - 19
kernel/src/sched/cfs.rs

@@ -1,24 +1,17 @@
-use core::{
-    ptr::null_mut,
-    sync::atomic::compiler_fence,
-};
+use core::{ptr::null_mut, sync::atomic::compiler_fence};
 
 use alloc::{boxed::Box, vec::Vec};
 
 use crate::{
-    arch::{
-        asm::current::current_pcb,
-        context::switch_process,
-    },
+    arch::asm::current::current_pcb,
     include::bindings::bindings::{
-        initial_proc_union, process_control_block, MAX_CPU_NUM, PF_NEED_SCHED,
-        PROC_RUNNING,
+        initial_proc_union, process_control_block, MAX_CPU_NUM, PF_NEED_SCHED, PROC_RUNNING,
     },
     kBUG,
     libs::spinlock::RawSpinlock,
 };
 
-use super::core::Scheduler;
+use super::core::{sched_enqueue, Scheduler};
 
 /// 声明全局的cfs调度器实例
 
@@ -149,8 +142,7 @@ impl SchedulerCFS {
 impl Scheduler for SchedulerCFS {
     /// @brief 在当前cpu上进行调度。
     /// 请注意,进入该函数之前,需要关中断
-    fn sched(&mut self) {
-        // kdebug!("cfs:sched");
+    fn sched(&mut self) -> Option<&'static mut process_control_block> {
         current_pcb().flags &= !(PF_NEED_SCHED as u64);
         let current_cpu_id = current_pcb().cpu_id as usize;
         let current_cpu_queue: &mut CFSQueue = self.cpu_queue[current_cpu_id];
@@ -163,8 +155,7 @@ impl Scheduler for SchedulerCFS {
             compiler_fence(core::sync::atomic::Ordering::SeqCst);
             // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
             if current_pcb().state & (PROC_RUNNING as u64) != 0 {
-                // kdebug!("cfs:sched->enqueue");
-                current_cpu_queue.enqueue(current_pcb());
+                sched_enqueue(current_pcb());
                 compiler_fence(core::sync::atomic::Ordering::SeqCst);
             }
 
@@ -175,9 +166,7 @@ impl Scheduler for SchedulerCFS {
             }
 
             compiler_fence(core::sync::atomic::Ordering::SeqCst);
-
-            switch_process(current_pcb(), proc);
-            compiler_fence(core::sync::atomic::Ordering::SeqCst);
+            return Some(proc);
         } else {
             // 不进行切换
 
@@ -188,10 +177,11 @@ impl Scheduler for SchedulerCFS {
             }
 
             compiler_fence(core::sync::atomic::Ordering::SeqCst);
-            current_cpu_queue.enqueue(proc);
+            sched_enqueue(proc);
             compiler_fence(core::sync::atomic::Ordering::SeqCst);
         }
         compiler_fence(core::sync::atomic::Ordering::SeqCst);
+        return None;
     }
 
     fn enqueue(&mut self, pcb: &'static mut process_control_block) {

+ 43 - 8
kernel/src/sched/core.rs

@@ -2,11 +2,16 @@ use core::sync::atomic::compiler_fence;
 
 use crate::{
     arch::asm::{current::current_pcb, ptrace::user_mode},
-    include::bindings::bindings::{process_control_block, pt_regs, EPERM, SCHED_NORMAL},
+    arch::context::switch_process,
+    include::bindings::bindings::{
+        process_control_block, pt_regs, EPERM, PROC_RUNNING, SCHED_FIFO, SCHED_NORMAL, SCHED_RR,
+    },
+    kdebug,
     process::process::process_cpu,
 };
 
 use super::cfs::{sched_cfs_init, SchedulerCFS, __get_cfs_scheduler};
+use super::rt::{sched_rt_init, SchedulerRT, __get_rt_scheduler};
 
 /// @brief 获取指定的cpu上正在执行的进程的pcb
 #[inline]
@@ -23,28 +28,50 @@ pub fn cpu_executing(cpu_id: u32) -> &'static mut process_control_block {
 /// @brief 具体的调度器应当实现的trait
 pub trait Scheduler {
     /// @brief 使用该调度器发起调度的时候,要调用的函数
-    fn sched(&mut self);
+    fn sched(&mut self) -> Option<&'static mut process_control_block>;
 
     /// @brief 将pcb加入这个调度器的调度队列
     fn enqueue(&mut self, pcb: &'static mut process_control_block);
 }
 
-fn __sched() {
+fn __sched() -> Option<&'static mut process_control_block> {
     compiler_fence(core::sync::atomic::Ordering::SeqCst);
     let cfs_scheduler: &mut SchedulerCFS = __get_cfs_scheduler();
+    let rt_scheduler: &mut SchedulerRT = __get_rt_scheduler();
     compiler_fence(core::sync::atomic::Ordering::SeqCst);
 
-    cfs_scheduler.sched();
-
-    compiler_fence(core::sync::atomic::Ordering::SeqCst);
+    let next: &'static mut process_control_block;
+    match rt_scheduler.pick_next_task_rt() {
+        Some(p) => {
+            next = p;
+            // kdebug!("next pcb is {}",next.pid);
+            // rt_scheduler.enqueue_task_rt(next.priority as usize, next);
+            sched_enqueue(next);
+            return rt_scheduler.sched();
+        }
+        None => {
+            return cfs_scheduler.sched();
+        }
+    }
 }
 
 /// @brief 将进程加入调度队列
 #[allow(dead_code)]
 #[no_mangle]
 pub extern "C" fn sched_enqueue(pcb: &'static mut process_control_block) {
+    // 调度器不处理running位为0的进程
+    if pcb.state & (PROC_RUNNING as u64) == 0 {
+        return;
+    }
     let cfs_scheduler = __get_cfs_scheduler();
-    cfs_scheduler.enqueue(pcb);
+    let rt_scheduler = __get_rt_scheduler();
+    if pcb.policy == SCHED_NORMAL {
+        cfs_scheduler.enqueue(pcb);
+    } else if pcb.policy == SCHED_FIFO || pcb.policy == SCHED_RR {
+        rt_scheduler.enqueue(pcb);
+    } else {
+        panic!("This policy is not supported at this time");
+    }
 }
 
 /// @brief 初始化进程调度器模块
@@ -53,6 +80,7 @@ pub extern "C" fn sched_enqueue(pcb: &'static mut process_control_block) {
 pub extern "C" fn sched_init() {
     unsafe {
         sched_cfs_init();
+        sched_rt_init();
     }
 }
 
@@ -65,6 +93,9 @@ pub extern "C" fn sched_update_jiffies() {
         SCHED_NORMAL => {
             __get_cfs_scheduler().timer_update_jiffies();
         }
+        SCHED_FIFO | SCHED_RR => {
+            current_pcb().rt_time_slice -= 1;
+        }
         _ => {
             todo!()
         }
@@ -80,6 +111,10 @@ pub extern "C" fn sys_sched(regs: &'static mut pt_regs) -> u64 {
     if user_mode(regs) {
         return (-(EPERM as i64)) as u64;
     }
-    __sched();
+    // 根据调度结果统一进行切换
+    let pcb = __sched();
+    if pcb.is_some() {
+        switch_process(current_pcb(), pcb.unwrap());
+    }
     0
 }

+ 2 - 1
kernel/src/sched/mod.rs

@@ -1,2 +1,3 @@
+pub mod cfs;
 pub mod core;
-pub mod cfs;
+pub mod rt;

+ 173 - 0
kernel/src/sched/rt.rs

@@ -0,0 +1,173 @@
+use core::{ptr::null_mut, sync::atomic::compiler_fence};
+
+use alloc::{boxed::Box, vec::Vec};
+
+use crate::{
+    arch::asm::current::current_pcb,
+    include::bindings::bindings::{
+        initial_proc_union, process_control_block, PF_NEED_SCHED, SCHED_FIFO, SCHED_NORMAL,
+        SCHED_RR,
+    },
+    kBUG, kdebug,
+    libs::spinlock::RawSpinlock,
+};
+
+use super::core::{sched_enqueue, Scheduler};
+
+/// 声明全局的rt调度器实例
+
+pub static mut RT_SCHEDULER_PTR: *mut SchedulerRT = null_mut();
+
+/// @brief 获取rt调度器实例的可变引用
+#[inline]
+pub fn __get_rt_scheduler() -> &'static mut SchedulerRT {
+    return unsafe { RT_SCHEDULER_PTR.as_mut().unwrap() };
+}
+
+/// @brief 初始化rt调度器
+pub unsafe fn sched_rt_init() {
+    kdebug!("test rt init");
+    if RT_SCHEDULER_PTR.is_null() {
+        RT_SCHEDULER_PTR = Box::leak(Box::new(SchedulerRT::new()));
+    } else {
+        kBUG!("Try to init RT Scheduler twice.");
+        panic!("Try to init RT Scheduler twice.");
+    }
+}
+
+/// @brief RT队列(per-cpu的)
+#[derive(Debug)]
+struct RTQueue {
+    /// 队列的锁
+    lock: RawSpinlock,
+    /// 进程的队列
+    queue: Vec<&'static mut process_control_block>,
+}
+
+impl RTQueue {
+    pub fn new() -> RTQueue {
+        RTQueue {
+            queue: Vec::new(),
+            lock: RawSpinlock::INIT,
+        }
+    }
+    /// @brief 将pcb加入队列
+    pub fn enqueue(&mut self, pcb: &'static mut process_control_block) {
+        self.lock.lock();
+
+        // 如果进程是IDLE进程,那么就不加入队列
+        if pcb.pid == 0 {
+            self.lock.unlock();
+            return;
+        }
+        self.queue.push(pcb);
+        self.lock.unlock();
+    }
+
+    /// @brief 将pcb从调度队列中弹出,若队列为空,则返回None
+    pub fn dequeue(&mut self) -> Option<&'static mut process_control_block> {
+        let res: Option<&'static mut process_control_block>;
+        self.lock.lock();
+        if self.queue.len() > 0 {
+            // 队列不为空,返回下一个要执行的pcb
+            res = Some(self.queue.pop().unwrap());
+        } else {
+            // 如果队列为空,则返回None
+            res=None;
+        }
+        self.lock.unlock();
+        return res;
+    }
+
+}
+
+/// @brief RT调度器类
+pub struct SchedulerRT {
+    cpu_queue: Vec<&'static mut RTQueue>,
+}
+
+impl SchedulerRT {
+    const RR_TIMESLICE: i64 = 100;
+    const MAX_RT_PRIO: i64 = 100;
+
+    pub fn new() -> SchedulerRT {
+        // 暂时手动指定核心数目
+        // todo: 从cpu模块来获取核心的数目
+        let mut result = SchedulerRT {
+            cpu_queue: Default::default(),
+        };
+
+        // 为每个cpu核心创建队列
+        for _ in 0..SchedulerRT::MAX_RT_PRIO {
+            result.cpu_queue.push(Box::leak(Box::new(RTQueue::new())));
+        }
+        return result;
+    }
+    /// @brief 挑选下一个可执行的rt进程
+    pub fn pick_next_task_rt(&mut self) -> Option<&'static mut process_control_block> {
+        // 循环查找,直到找到
+        // 这里应该是优先级数量,而不是CPU数量,需要修改
+        for i in 0..SchedulerRT::MAX_RT_PRIO {
+            let cpu_queue_i: &mut RTQueue = self.cpu_queue[i as usize];
+            let proc: Option<&'static mut process_control_block> = cpu_queue_i.dequeue();
+            if proc.is_some(){
+                return proc;
+            }
+        }
+        // return 一个空值
+        None
+    }
+}
+
+impl Scheduler for SchedulerRT {
+    /// @brief 在当前cpu上进行调度。
+    /// 请注意,进入该函数之前,需要关中断
+    fn sched(&mut self) -> Option<&'static mut process_control_block> {
+        current_pcb().flags &= !(PF_NEED_SCHED as u64);
+        // 正常流程下,这里一定是会pick到next的pcb的,如果是None的话,要抛出错误
+        let proc: &'static mut process_control_block =
+            self.pick_next_task_rt().expect("No RT process found");
+
+        // 如果是fifo策略,则可以一直占有cpu直到有优先级更高的任务就绪(即使优先级相同也不行)或者主动放弃(等待资源)
+        if proc.policy == SCHED_FIFO {
+            // 如果挑选的进程优先级小于当前进程,则不进行切换
+            if proc.priority <= current_pcb().priority {
+                sched_enqueue(proc);
+            } else {
+                // 将当前的进程加进队列
+                sched_enqueue(current_pcb());
+                compiler_fence(core::sync::atomic::Ordering::SeqCst);
+                return Some(proc);
+            }
+        }
+        // RR调度策略需要考虑时间片
+        else if proc.policy == SCHED_RR {
+            // 同等优先级的,考虑切换
+            if proc.priority >= current_pcb().priority {
+                // 判断这个进程时间片是否耗尽,若耗尽则将其时间片赋初值然后入队
+                if proc.rt_time_slice <= 0 {
+                    proc.rt_time_slice = SchedulerRT::RR_TIMESLICE;
+                    proc.flags |= !(PF_NEED_SCHED as u64);
+                    sched_enqueue(proc);
+                }
+                // 目标进程时间片未耗尽,切换到目标进程
+                else {
+                    // 将当前进程加进队列
+                    sched_enqueue(current_pcb());
+                    compiler_fence(core::sync::atomic::Ordering::SeqCst);
+                    return Some(proc);
+                }
+            }
+            // curr优先级更大,说明一定是实时进程,将所选进程入队列
+            else {
+                sched_enqueue(proc);
+            }
+        }
+        return None;
+    }
+
+    fn enqueue(&mut self, pcb: &'static mut process_control_block) {
+        let cpu_queue = &mut self.cpu_queue[pcb.cpu_id as usize];
+        cpu_queue.enqueue(pcb);
+    }
+}

+ 1 - 1
kernel/src/smp/mod.rs

@@ -1 +1 @@
-pub mod core;
+pub mod core;