Sfoglia il codice sorgente

软中断&定时器重构 (#223)

* 软中断&定时器重构

Co-authored-by: houmkh<[email protected]>

* 修改timer的clock()

* 删除debug信息

---------

Co-authored-by: houmkh <[email protected]>
login 1 anno fa
parent
commit
bacd691c9e

+ 1 - 0
kernel/Cargo.toml

@@ -10,6 +10,7 @@ crate-type = ["staticlib"]
 
 # 运行时依赖项
 [dependencies]
+x86 = "0.52.0"
 x86_64 = "0.14.10"
 bitflags = "1.3.2"
 virtio-drivers = "0.3.0"

+ 1 - 1
kernel/src/Makefile

@@ -17,7 +17,7 @@ export ASFLAGS := --64
 LD_LIST := head.o
 
 
-kernel_subdirs := common driver process debug time arch exception mm smp sched syscall ktest libs ipc io
+kernel_subdirs := common driver process debug arch exception mm smp sched syscall ktest libs ipc io
 	
 
 

+ 5 - 11
kernel/src/arch/x86_64/cpu.rs

@@ -1,18 +1,12 @@
 use core::arch::asm;
 
+use super::asm::current::current_pcb;
+
 /// @brief 获取当前cpu的apic id
 #[inline]
-pub fn current_cpu_id() -> u8 {
-    let cpuid_res: u32;
-    unsafe {
-        asm!(
-             "mov eax, 1",
-             "cpuid",
-             "mov r15, rbx",
-             lateout("r15") cpuid_res
-        );
-    }
-    return ((cpuid_res >> 24) & 0xff) as u8;
+pub fn current_cpu_id() -> u32 {
+    // TODO: apic重构后,使用apic id来设置这里
+    current_pcb().cpu_id as u32
 }
 
 /// @brief 通过pause指令,让cpu休息一会儿。降低空转功耗

+ 6 - 7
kernel/src/common/time.h

@@ -21,19 +21,18 @@ struct tm
     const char *__tm_zone; /* Timezone abbreviation.  */
 };
 
-
 struct timespec
 {
-    int64_t tv_sec;    // 秒
-    int64_t tv_nsec;   // 纳秒
+    int64_t tv_sec;  // 秒
+    int64_t tv_nsec; // 纳秒
 };
 
 /**
  * @brief 休眠指定时间
- * 
+ *
  * @param rqtp 指定休眠的时间
  * @param rmtp 返回的剩余休眠时间
- * @return int 
+ * @return int
  */
 extern int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
 
@@ -47,7 +46,7 @@ extern int usleep(useconds_t usec);
 
 /**
  * @brief 获取当前的CPU时间
- * 
+ *
  * @return uint64_t timer_jiffies
  */
-extern uint64_t clock();
+extern uint64_t rs_clock();

+ 1 - 1
kernel/src/driver/interrupt/apic/apic.c

@@ -456,7 +456,7 @@ void do_IRQ(struct pt_regs *rsp, ul number)
 
     // kdebug("before softirq");
     // 进入软中断处理程序
-    do_softirq();
+    rs_do_softirq();
 
     // kdebug("after softirq");
     // 检测当前进程是否持有自旋锁,若持有自旋锁,则不进行抢占式的进程调度

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

@@ -4,4 +4,5 @@ pub mod pci;
 pub mod timers;
 pub mod tty;
 pub mod uart;
+pub mod video;
 pub mod virtio;

+ 8 - 8
kernel/src/driver/timers/HPET/HPET.c

@@ -67,7 +67,7 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
     switch (param)
     {
     case 0: // 定时器0中断
-        timer_jiffies += HPET0_INTERVAL;
+        rs_update_timer_jiffies(HPET0_INTERVAL);
 
         /*
         // 将HEPT中断消息转发到ap:1处理器
@@ -76,18 +76,18 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
                      */
 
         // 若当前时间比定时任务的时间间隔大,则进入中断下半部
-        if (container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list)->expire_jiffies <= timer_jiffies)
-            raise_softirq(TIMER_SIRQ);
+        if (rs_timer_get_first_expire() <= rs_clock())
+            rs_raise_softirq(TIMER_SIRQ);
 
         // 当时间到了,或进程发生切换时,刷新帧缓冲区
-        if (timer_jiffies >= video_refresh_expire_jiffies || (video_last_refresh_pid != current_pcb->pid))
+        if (rs_clock() >= video_refresh_expire_jiffies || (video_last_refresh_pid != current_pcb->pid))
         {
-            raise_softirq(VIDEO_REFRESH_SIRQ);
+            rs_raise_softirq(VIDEO_REFRESH_SIRQ);
             // 超过130ms仍未刷新完成,则重新发起刷新(防止由于进程异常退出导致的屏幕无法刷新)
-            if (unlikely(timer_jiffies >= (video_refresh_expire_jiffies + (1 << 17))))
+            if (unlikely(rs_clock() >= (video_refresh_expire_jiffies + (1 << 17))))
             {
-                video_refresh_expire_jiffies = timer_jiffies + (1 << 20);
-                clear_softirq_pending(VIDEO_REFRESH_SIRQ);
+                video_refresh_expire_jiffies = rs_clock() + (1 << 20);
+                rs_clear_softirq_pending(VIDEO_REFRESH_SIRQ);
             }
         }
         break;

+ 9 - 9
kernel/src/driver/usb/xhci/xhci.c

@@ -245,7 +245,7 @@ static int xhci_hc_stop(int id)
     while ((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 0)
     {
         io_mfence();
-        usleep(1000);
+        rs_usleep(1000);
         if (--timeout == 0)
             return -ETIMEDOUT;
     }
@@ -285,7 +285,7 @@ static int xhci_hc_reset(int id)
     while (xhci_read_op_reg32(id, XHCI_OPS_USBCMD) & (1 << 1))
     {
         io_mfence();
-        usleep(1000);
+        rs_usleep(1000);
         if (--timeout == 0)
             return -ETIMEDOUT;
     }
@@ -319,7 +319,7 @@ static int xhci_hc_stop_legacy(int id)
                    XHCI_XECP_LEGACY_OS_OWNED)
             {
                 io_mfence();
-                usleep(1000);
+                rs_usleep(1000);
                 if (--timeout == 0)
                 {
                     kerror("The BIOS doesn't stop legacy support.");
@@ -352,7 +352,7 @@ static int xhci_hc_start_sched(int id)
     io_mfence();
     xhci_write_op_reg32(id, XHCI_OPS_USBCMD, (1 << 0) | (1 << 2) | (1 << 3));
     io_mfence();
-    usleep(100 * 1000);
+    rs_usleep(100 * 1000);
 }
 
 /**
@@ -793,7 +793,7 @@ static int xhci_reset_port(const int id, const int port)
         io_mfence();
         xhci_write_cap_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9));
         io_mfence();
-        usleep(2000);
+        rs_usleep(2000);
         // 检测端口是否被启用, 若未启用,则报错
         if ((xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC) & (1 << 9)) == 0)
         {
@@ -833,14 +833,14 @@ static int xhci_reset_port(const int id, const int port)
             break;
 #endif
         --timeout;
-        usleep(500);
+        rs_usleep(500);
     }
     // kdebug("timeout= %d", timeout);
 
     if (timeout > 0)
     {
         // 等待恢复
-        usleep(USB_TIME_RST_REC * 100);
+        rs_usleep(USB_TIME_RST_REC * 100);
         uint32_t val = xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC);
         io_mfence();
 
@@ -1219,7 +1219,7 @@ static int xhci_wait_for_interrupt(const int id, uint64_t status_vaddr)
             }
         }
         --timer;
-        usleep(1000);
+        rs_usleep(1000);
     }
 
     kerror(" USB xHCI Interrupt wait timed out.");
@@ -2001,7 +2001,7 @@ static int xhci_send_command(int id, struct xhci_TRB_t *trb, const bool do_ring)
         // We use bit 31 of the command dword since it is reserved
         while (timer && ((__read4b(origin_trb_vaddr + 8) & XHCI_IRQ_DONE) == 0))
         {
-            usleep(1000);
+            rs_usleep(1000);
             --timer;
         }
         uint32_t x = xhci_read_cap_reg32(id, xhci_hc[id].rts_offset + 0x20);

+ 62 - 0
kernel/src/driver/video/mod.rs

@@ -0,0 +1,62 @@
+use core::{ptr::null_mut, sync::atomic::{AtomicBool, Ordering}};
+
+use alloc::sync::Arc;
+
+use crate::{
+    exception::softirq::{SoftirqNumber, SoftirqVec, softirq_vectors},
+    include::bindings::bindings::video_refresh_framebuffer,
+};
+
+#[derive(Debug)]
+pub struct VideoRefreshFramebuffer{
+    running: AtomicBool
+}
+
+impl SoftirqVec for VideoRefreshFramebuffer {
+    fn run(&self) {
+        if self.set_run() == false{
+            return;
+        }
+        
+        unsafe {
+            video_refresh_framebuffer(null_mut());
+        }
+
+        self.clear_run();
+    }
+}
+impl VideoRefreshFramebuffer {
+    pub fn new() -> VideoRefreshFramebuffer {
+        VideoRefreshFramebuffer {
+            running: AtomicBool::new(false)
+        }
+    }
+
+    fn set_run(&self) -> bool {
+        let x = self
+            .running
+            .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed);
+        if x.is_ok() {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    fn clear_run(&self) {
+        self.running.store(false, Ordering::Release);
+    }
+}
+
+pub fn register_softirq_video() {
+    // kdebug!("register_softirq_video");
+    let handler = Arc::new(VideoRefreshFramebuffer::new());
+    softirq_vectors()
+        .register_softirq(SoftirqNumber::VideoRefresh, handler)
+        .expect("register_softirq_video run failed");
+}
+// ======= 以下为给C提供的接口,video重构完后请删除 =======
+#[no_mangle]
+pub extern "C" fn rs_register_softirq_video() {
+    register_softirq_video();
+}

+ 14 - 11
kernel/src/driver/video/video.c

@@ -13,6 +13,8 @@
 #include <sched/sched.h>
 #include <time/timer.h>
 
+extern void rs_register_softirq_video();
+
 uint64_t video_refresh_expire_jiffies = 0;
 uint64_t video_last_refresh_pid = -1;
 
@@ -57,7 +59,7 @@ int video_refresh_daemon(void *unused)
 
     for (;;)
     {
-        if (clock() >= video_refresh_expire_jiffies)
+        if (rs_clock() >= video_refresh_expire_jiffies)
         {
 
             if (likely(video_refresh_target != NULL))
@@ -68,7 +70,7 @@ int video_refresh_daemon(void *unused)
                 spin_unlock(&daemon_refresh_lock);
                 video_daemon_pcb->virtual_runtime = 0xfffff0000000; // 临时解决由于显示刷新进程的虚拟运行时间过大/过小,导致其不运行,或者一直运行的问题。将来应使用实时调度解决它
             }
-            video_refresh_expire_jiffies = cal_next_n_ms_jiffies(REFRESH_INTERVAL << 1);
+            video_refresh_expire_jiffies = rs_timer_next_n_ms_jiffies(REFRESH_INTERVAL << 1);
         }
         video_daemon_pcb->state &= ~PROC_RUNNING;
         video_daemon_pcb->flags |= PF_NEED_SCHED;
@@ -85,7 +87,7 @@ void video_refresh_framebuffer(void *data)
 {
     if (unlikely(video_daemon_pcb == NULL))
         return;
-    if (clock() >= video_refresh_expire_jiffies)
+    if (rs_clock() >= video_refresh_expire_jiffies)
     {
         video_daemon_pcb->virtual_runtime = 0;
         process_wakeup(video_daemon_pcb);
@@ -105,18 +107,18 @@ int video_reinitialize(bool level) // 这个函数会在main.c调用, 保证 vid
         init_frame_buffer();
     else
     {
-        unregister_softirq(VIDEO_REFRESH_SIRQ);
+        rs_unregister_softirq(VIDEO_REFRESH_SIRQ);
         // 计算开始时间
-        video_refresh_expire_jiffies = cal_next_n_ms_jiffies(10 * REFRESH_INTERVAL);
+        video_refresh_expire_jiffies = rs_timer_next_n_ms_jiffies(10 * REFRESH_INTERVAL);
 
         // 创建video守护进程
         video_daemon_pcb = kthread_run(&video_refresh_daemon, NULL, "Video refresh daemon");
         video_daemon_pcb->virtual_runtime = 0; // 特殊情况, 最高优先级, 以后再改
 
         // 启用屏幕刷新软中断
-        register_softirq(VIDEO_REFRESH_SIRQ, &video_refresh_framebuffer, NULL);
+        rs_register_softirq_video();
 
-        raise_softirq(VIDEO_REFRESH_SIRQ);
+        rs_raise_softirq(VIDEO_REFRESH_SIRQ);
     }
     return 0;
 }
@@ -130,7 +132,7 @@ int video_reinitialize(bool level) // 这个函数会在main.c调用, 保证 vid
 int video_set_refresh_target(struct scm_buffer_info_t *buf)
 {
 
-    unregister_softirq(VIDEO_REFRESH_SIRQ);
+    rs_unregister_softirq(VIDEO_REFRESH_SIRQ);
     // todo: 在completion实现后,在这里等待其他刷新任务完成,再进行下一步。
 
     // int counter = 100;
@@ -138,12 +140,13 @@ int video_set_refresh_target(struct scm_buffer_info_t *buf)
     // while ((get_softirq_pending() & (1 << VIDEO_REFRESH_SIRQ)) && counter > 0)
     // {
     //     --counter;
-    //     usleep(1000);
+    //     rs_usleep(1000);
     // }
     // kdebug("buf = %#018lx", buf);
     video_refresh_target = buf;
-    register_softirq(VIDEO_REFRESH_SIRQ, &video_refresh_framebuffer, NULL);
-    raise_softirq(VIDEO_REFRESH_SIRQ);
+    rs_register_softirq_video();
+    kdebug("register softirq video done");
+    // rs_raise_softirq(VIDEO_REFRESH_SIRQ);
 }
 
 /**

+ 1 - 1
kernel/src/driver/video/video.h

@@ -30,4 +30,4 @@ int video_set_refresh_target(struct scm_buffer_info_t *buf);
 extern uint64_t video_refresh_expire_jiffies;
 extern uint64_t video_last_refresh_pid;
 
-extern void video_refresh_framebuffer();
+void video_refresh_framebuffer(void *data);

+ 29 - 29
kernel/src/driver/virtio/virtio.rs

@@ -80,7 +80,7 @@ fn virtio_device(transport: impl Transport) {
 
 ///@brief virtio-net 驱动的初始化与测试
 fn virtio_net<T: Transport>(transport: T) {
-    let mut driver_net = match VirtIONet::<HalImpl, T>::new(transport) {
+    let driver_net = match VirtIONet::<HalImpl, T>::new(transport) {
         Ok(net) => {
             kdebug!("Virtio-net driver init successfully.");
             net
@@ -90,40 +90,40 @@ fn virtio_net<T: Transport>(transport: T) {
             return;
         }
     };
-    let mut buf = [0u8; 0x100];
-    // let len = match driver_net.recv(&mut buf)
-    // {
-    //     Ok(len) =>{len},
-    //     Err(_) =>{kerror!("virtio_net recv failed");return;}
-    // };
-    match driver_net.can_send() {
-        true => {
-            kdebug!("Virtio-net can send");
-        }
-        false => {
-            kdebug!("Virtio-net can not send");
-        }
-    }
-    // match driver_net.can_recv() {
+    // let mut buf = [0u8; 0x100];
+    // // let len = match driver_net.recv(&mut buf)
+    // // {
+    // //     Ok(len) =>{len},
+    // //     Err(_) =>{kerror!("virtio_net recv failed");return;}
+    // // };
+    // match driver_net.can_send() {
     //     true => {
-    //         kdebug!("can recv")
+    //         kdebug!("Virtio-net can send");
     //     }
     //     false => {
-    //         kdebug!("can not recv");
+    //         kdebug!("Virtio-net can not send");
     //     }
     // }
+    // // match driver_net.can_recv() {
+    // //     true => {
+    // //         kdebug!("can recv")
+    // //     }
+    // //     false => {
+    // //         kdebug!("can not recv");
+    // //     }
+    // // }
 
-    let len = 100;
-    //kdebug!("recv: {:?}", &buf[..len]);
-    match driver_net.send(&buf[..len]) {
-        Ok(_) => {
-            kdebug!("virtio_net send success");
-        }
-        Err(_) => {
-            kerror!("virtio_net send failed");
-            return;
-        }
-    }
+    // let len = 100;
+    // //kdebug!("recv: {:?}", &buf[..len]);
+    // match driver_net.send(&buf[..len]) {
+    //     Ok(_) => {
+    //         kdebug!("virtio_net send success");
+    //     }
+    //     Err(_) => {
+    //         kerror!("virtio_net send failed");
+    //         return;
+    //     }
+    // }
 
     let mac = driver_net.mac();
     kdebug!("virtio_net MAC={:?}", mac);

+ 4 - 4
kernel/src/exception/softirq.h

@@ -13,11 +13,11 @@
 #include <common/glib.h>
 
 // ==================implementation with rust===================
-extern void softirq_init();
-extern void raise_softirq(uint32_t sirq_num);
-extern int register_softirq(uint32_t irq_num, void (*action)(void *data), void *data);
+extern void rs_softirq_init();
+extern void rs_raise_softirq(uint32_t sirq_num);
+extern int rs_register_softirq(uint32_t irq_num, void (*action)(void *data), void *data);
 extern int unregister_softirq(uint32_t irq_num);
-extern void do_softirq();
+extern void rs_do_softirq();
 
 // for temporary
 #define MAX_SOFTIRQ_NUM 64

+ 208 - 211
kernel/src/exception/softirq.rs

@@ -1,268 +1,265 @@
-use core::{ffi::c_void, ptr::null_mut};
+use core::{
+    fmt::Debug,
+    intrinsics::unlikely,
+    mem::{self, MaybeUninit},
+    ptr::null_mut,
+    sync::atomic::{compiler_fence, Ordering},
+};
 
-use alloc::boxed::Box;
+use alloc::{boxed::Box, sync::Arc};
+use num_traits::FromPrimitive;
 
 use crate::{
-    arch::interrupt::{cli, sti},
-    include::bindings::bindings::verify_area,
-    kBUG,
-    libs::spinlock::RawSpinlock,
-    syscall::SystemError, kdebug,
+    arch::{
+        asm::{
+            current::current_pcb,
+            irqflags::{local_irq_restore, local_irq_save},
+        },
+        interrupt::{cli, sti},
+    },
+    include::bindings::bindings::MAX_CPU_NUM,
+    kdebug, kinfo,
+    libs::rwlock::RwLock,
+    smp::core::smp_get_processor_id,
+    syscall::SystemError,
+    time::timer::clock,
 };
 
 const MAX_SOFTIRQ_NUM: u64 = 64;
-const MAX_LOCK_TRIAL_TIME: u64 = 50;
-pub static mut SOFTIRQ_HANDLER_PTR: *mut Softirq = null_mut();
+const MAX_SOFTIRQ_RESTART: i32 = 20;
 
-/// 软中断向量号码
-#[allow(dead_code)]
-#[repr(u8)]
-pub enum SoftirqNumber {
-    TIMER = 0,        //时钟软中断信号
-    VideoRefresh = 1, //帧缓冲区刷新软中断
-}
+static mut __CPU_PENDING: Option<Box<[VecStatus; MAX_CPU_NUM as usize]>> = None;
+static mut __SORTIRQ_VECTORS: *mut Softirq = null_mut();
 
-#[repr(C)]
-#[derive(Clone, Copy)]
-pub struct SoftirqVector {
-    pub action: Option<unsafe extern "C" fn(data: *mut ::core::ffi::c_void)>, //软中断处理函数
-    pub data: *mut c_void,
+#[no_mangle]
+pub extern "C" fn rs_softirq_init() {
+    softirq_init().expect("softirq_init failed");
 }
 
-impl Default for SoftirqVector {
-    fn default() -> Self {
-        Self {
-            action: None,
-            data: null_mut(),
+pub fn softirq_init() -> Result<(), SystemError> {
+    kinfo!("Initializing softirq...");
+    unsafe {
+        __SORTIRQ_VECTORS = Box::leak(Box::new(Softirq::new()));
+        __CPU_PENDING = Some(Box::new([VecStatus::default(); MAX_CPU_NUM as usize]));
+        let cpu_pending = __CPU_PENDING.as_mut().unwrap();
+        for i in 0..MAX_CPU_NUM {
+            cpu_pending[i as usize] = VecStatus::default();
         }
     }
+    return Ok(());
 }
 
-pub struct Softirq {
-    modify_lock: RawSpinlock,
-    pending: u64,
-    running: u64,
-    table: [SoftirqVector; MAX_SOFTIRQ_NUM as usize],
-}
-
-#[no_mangle]
-#[allow(dead_code)]
-/// @brief 提供给c的接口函数,用于初始化静态指针
-pub extern "C" fn softirq_init() {
-    if unsafe { SOFTIRQ_HANDLER_PTR.is_null() } {
-        unsafe {
-            SOFTIRQ_HANDLER_PTR = Box::leak(Box::new(Softirq::default()));
-        }
-    } else {
-        kBUG!("Try to init SOFTIRQ_HANDLER_PTR twice.");
-        panic!("Try to init SOFTIRQ_HANDLER_PTR twice.");
+#[inline(always)]
+pub fn softirq_vectors() -> &'static mut Softirq {
+    unsafe {
+        return __SORTIRQ_VECTORS.as_mut().unwrap();
     }
 }
 
-/// @brief 将raw pointer转换为指针,减少unsafe块
-#[inline]
-pub fn __get_softirq_handler_mut() -> &'static mut Softirq {
-    return unsafe { SOFTIRQ_HANDLER_PTR.as_mut().unwrap() };
+#[inline(always)]
+fn cpu_pending(cpu_id: usize) -> &'static mut VecStatus {
+    unsafe {
+        return &mut __CPU_PENDING.as_mut().unwrap()[cpu_id];
+    }
 }
 
-#[no_mangle]
+/// 软中断向量号码
 #[allow(dead_code)]
-pub extern "C" fn raise_softirq(sirq_num: u32) {
-    let softirq_handler = __get_softirq_handler_mut();
-    softirq_handler.set_softirq_pending(sirq_num);
+#[repr(u8)]
+#[derive(FromPrimitive, Copy, Clone, Debug, PartialEq, Eq)]
+pub enum SoftirqNumber {
+    /// 时钟软中断信号
+    TIMER = 0,
+    VideoRefresh = 1, //帧缓冲区刷新软中断
 }
 
-/// @brief 软中断注册函数
-///
-/// @param irq_num 软中断号
-/// @param action 响应函数
-/// @param data 响应数据结构体
-#[no_mangle]
-#[allow(dead_code)]
-pub extern "C" fn register_softirq(
-    irq_num: u32,
-    action: Option<unsafe extern "C" fn(data: *mut ::core::ffi::c_void)>,
-    data: *mut c_void,
-) {
-    let softirq_handler = __get_softirq_handler_mut();
-    softirq_handler.register_softirq(irq_num, action, data).expect(&format!("Softirq: Failed to register {}", irq_num));
+impl From<u64> for SoftirqNumber {
+    fn from(value: u64) -> Self {
+        return <Self as FromPrimitive>::from_u64(value).unwrap();
+    }
 }
 
-/// @brief 卸载软中断
-/// @param irq_num 软中断号
-#[no_mangle]
-#[allow(dead_code)]
-pub extern "C" fn unregister_softirq(irq_num: u32) {
-    let softirq_handler = __get_softirq_handler_mut();
-    softirq_handler.unregister_softirq(irq_num).expect(&format!("Softirq: Failed to unregister {}", irq_num));
+bitflags! {
+    #[derive(Default)]
+    pub struct VecStatus: u64 {
+        const TIMER = 1 << 0;
+        const VIDEO_REFRESH = 1 << 1;
+    }
 }
 
-/// 设置软中断的运行状态(只应在do_softirq中调用此宏)
-#[no_mangle]
-#[allow(dead_code)]
-pub extern "C" fn set_softirq_pending(irq_num: u32) {
-    let softirq_handler = __get_softirq_handler_mut();
-    softirq_handler.set_softirq_pending(irq_num);
+impl From<SoftirqNumber> for VecStatus {
+    fn from(value: SoftirqNumber) -> Self {
+        return Self::from_bits_truncate(1 << (value as u64));
+    }
 }
 
-/// @brief 设置软中断运行结束
-///
-/// @param softirq_num
-#[no_mangle]
-#[allow(dead_code)]
-pub extern "C" fn clear_softirq_pending(irq_num: u32) {
-    let softirq_handler = __get_softirq_handler_mut();
-    softirq_handler.clear_softirq_pending(irq_num);
+pub trait SoftirqVec: Send + Sync + Debug {
+    fn run(&self);
 }
 
-/// @brief 软中断处理程序
-#[no_mangle]
-#[allow(dead_code)]
-pub extern "C" fn do_softirq() {
-    let softirq_handler = __get_softirq_handler_mut();
-    softirq_handler.do_softirq();
+#[derive(Debug)]
+pub struct Softirq {
+    table: RwLock<[Option<Arc<dyn SoftirqVec>>; MAX_SOFTIRQ_NUM as usize]>,
 }
+impl Softirq {
+    fn new() -> Softirq {
+        let mut data: [MaybeUninit<Option<Arc<dyn SoftirqVec>>>; MAX_SOFTIRQ_NUM as usize] =
+            unsafe { MaybeUninit::uninit().assume_init() };
 
-impl Default for Softirq {
-    fn default() -> Self {
-        Self {
-            modify_lock: RawSpinlock::INIT,
-            pending: (0),
-            running: (0),
-            table: [Default::default(); MAX_SOFTIRQ_NUM as usize],
+        for i in 0..MAX_SOFTIRQ_NUM {
+            data[i as usize] = MaybeUninit::new(None);
         }
-    }
-}
 
-impl Softirq {
-    #[inline]
-    #[allow(dead_code)]
-    pub fn get_softirq_pending(&self) -> u64 {
-        return self.pending;
-    }
+        let data: [Option<Arc<dyn SoftirqVec>>; MAX_SOFTIRQ_NUM as usize] = unsafe {
+            mem::transmute::<_, [Option<Arc<dyn SoftirqVec>>; MAX_SOFTIRQ_NUM as usize]>(data)
+        };
 
-    #[inline]
-    #[allow(dead_code)]
-    pub fn get_softirq_running(&self) -> u64 {
-        return self.running;
+        return Softirq {
+            table: RwLock::new(data),
+        };
     }
 
-    #[inline]
-    pub fn set_softirq_pending(&mut self, softirq_num: u32) {
-        self.pending |= 1 << softirq_num;
-    }
+    /// @brief 注册软中断向量
+    ///
+    /// @param softirq_num 中断向量号
+    ///
+    /// @param hanlder 中断函数对应的结构体
+    pub fn register_softirq(
+        &self,
+        softirq_num: SoftirqNumber,
+        handler: Arc<dyn SoftirqVec>,
+    ) -> Result<i32, SystemError> {
+        // kdebug!("register_softirq softirq_num = {:?}", softirq_num as u64);
 
-    #[inline]
-    pub fn set_softirq_running(&mut self, softirq_num: u32) {
-        self.running |= 1 << softirq_num;
-    }
+        // let self = &mut SOFTIRQ_VECTORS.lock();
+        // 判断该软中断向量是否已经被注册
+        let mut table_guard = self.table.write();
+        if table_guard[softirq_num as usize].is_some() {
+            // kdebug!("register_softirq failed");
 
-    #[inline]
-    pub fn clear_softirq_running(&mut self, softirq_num: u32) {
-        self.running &= !(1 << softirq_num);
-    }
+            return Err(SystemError::EINVAL);
+        }
+        table_guard[softirq_num as usize] = Some(handler);
+        drop(table_guard);
 
-    /// @brief 清除软中断pending标志位
-    #[inline]
-    pub fn clear_softirq_pending(&mut self, softirq_num: u32) {
-        self.pending &= !(1 << softirq_num);
+        // kdebug!(
+        //     "register_softirq successfully, softirq_num = {:?}",
+        //     softirq_num as u64
+        // );
+        compiler_fence(Ordering::SeqCst);
+        return Ok(0);
     }
 
-    /// @brief 判断对应running标志位是否为0
-    /// @return true: 标志位为1; false: 标志位为0
-    #[inline]
-    pub fn is_running(&mut self, softirq_num: u32) -> bool {
-        return (self.running & (1 << softirq_num)).ne(&0);
+    /// @brief 解注册软中断向量
+    ///
+    /// @param irq_num 中断向量号码   
+    pub fn unregister_softirq(&self, softirq_num: SoftirqNumber) {
+        // kdebug!("unregister_softirq softirq_num = {:?}", softirq_num as u64);
+        let table_guard = &mut self.table.write();
+        // 将软中断向量清空
+        table_guard[softirq_num as usize] = None;
+        drop(table_guard);
+        // 将对应位置的pending和runing都置0
+        // self.running.lock().set(VecStatus::from(softirq_num), false);
+        // 将对应CPU的pending置0
+        compiler_fence(Ordering::SeqCst);
+        cpu_pending(smp_get_processor_id() as usize).set(VecStatus::from(softirq_num), false);
+        compiler_fence(Ordering::SeqCst);
     }
 
-    /// @brief 判断对应pending标志位是否为0
-    /// @return true: 标志位为1; false: 标志位为0
-    #[inline]
-    pub fn is_pending(&mut self, softirq_num: u32) -> bool {
-        return (self.pending & (1 << softirq_num)).ne(&0);
-    }
+    pub fn do_softirq(&self) {
+        // TODO pcb的flags未修改
+        // todo: 是否需要判断在当前cpu上面,该函数的嵌套层数?(防止爆栈)
+        let end = clock() + 500 * 2;
+        let cpu_id = smp_get_processor_id();
+        let mut max_restart = MAX_SOFTIRQ_RESTART;
+        loop {
+            compiler_fence(Ordering::SeqCst);
+            let pending = cpu_pending(cpu_id as usize).bits;
+            cpu_pending(cpu_id as usize).bits = 0;
+            compiler_fence(Ordering::SeqCst);
 
-    /// @brief 注册软中断向量
-    /// @param irq_num 中断向量号码
-    /// @param action 中断函数的入口地址
-    /// @param data 中断函数的操作数据
-    pub fn register_softirq(
-        &mut self,
-        irq_num: u32,
-        action: Option<unsafe extern "C" fn(data: *mut ::core::ffi::c_void)>,
-        data: *mut c_void,
-    ) -> Result<(), SystemError> {
-        if self.table[irq_num as usize].action.is_some() {
-            return Err(SystemError::EEXIST);
-        }
+            sti();
+            if pending != 0 {
+                for i in 0..MAX_SOFTIRQ_NUM {
+                    if pending & (1 << i) == 0 {
+                        continue;
+                    }
 
-        if unsafe { verify_area(action.unwrap() as u64, 1) } {
-            return Err(SystemError::EPERM);
-        }
-        self.modify_lock.lock();
-        self.table[irq_num as usize].action = action;
-        self.table[irq_num as usize].data = data;
-        self.modify_lock.unlock();
-        return Ok(());
-    }
+                    let table_guard = self.table.read();
+                    let softirq_func = table_guard[i as usize].clone();
+                    drop(table_guard);
+                    if softirq_func.is_none() {
+                        continue;
+                    }
 
-    /// @brief 解注册软中断向量
-    /// @param irq_num 中断向量号码
-    pub fn unregister_softirq(&mut self, irq_num: u32) -> Result<(), SystemError> {
-        for _trial_time in 0..MAX_LOCK_TRIAL_TIME {
-            if self.is_running(irq_num) {
-                continue; //running标志位为1
+                    let prev_count = current_pcb().preempt_count;
+
+                    softirq_func.as_ref().unwrap().run();
+                    if unlikely(prev_count != current_pcb().preempt_count) {
+                        kdebug!(
+                            "entered softirq {:?} with preempt_count {:?},exited with {:?}",
+                            i,
+                            prev_count,
+                            current_pcb().preempt_count
+                        );
+                        current_pcb().preempt_count = prev_count;
+                    }
+                }
             }
-            if self.modify_lock.try_lock() {
-                if self.is_running(irq_num) {
-                    self.modify_lock.unlock();
+            cli();
+            max_restart -= 1;
+            compiler_fence(Ordering::SeqCst);
+            if cpu_pending(cpu_id as usize).is_empty() {
+                compiler_fence(Ordering::SeqCst);
+                if clock() < end && max_restart > 0 {
                     continue;
+                } else {
+                    break;
                 }
+            } else {
+                // TODO:当有softirqd时 唤醒它
                 break;
             }
         }
-        // 存在尝试加锁规定次数后仍加锁失败的情况,报告错误并退出
-        if !self.modify_lock.is_locked() {
-            return Err(SystemError::EBUSY);
-        }
-        kdebug!("SOftirq: unregister {irq_num}");
-        self.clear_softirq_running(irq_num);
-        self.clear_softirq_pending(irq_num);
-        self.table[irq_num as usize].action = None;
-        self.table[irq_num as usize].data = null_mut();
-        self.modify_lock.unlock();
-        return Ok(());
     }
 
-    /// @brief 遍历执行软中断
-    pub fn do_softirq(&mut self) {
-        sti();
-        let mut softirq_index: u32 = 0; //软中断向量号码
-        while (softirq_index as u64) < MAX_SOFTIRQ_NUM && self.pending != 0 {
-            if self.is_pending(softirq_index)
-                && self.table[softirq_index as usize].action.is_some()
-                && !self.is_running(softirq_index)
-            {
-                if self.modify_lock.try_lock() {
-                    if self.is_running(softirq_index)
-                        || self.table[softirq_index as usize].action.is_none()
-                    {
-                        self.modify_lock.unlock();
-                        continue;
-                    }
-                    self.clear_softirq_pending(softirq_index);
-                    self.set_softirq_running(softirq_index);
-                    self.modify_lock.unlock();
-                    unsafe {
-                        (self.table[softirq_index as usize].action.unwrap())(
-                            self.table[softirq_index as usize].data,
-                        );
-                    }
-                    self.clear_softirq_running(softirq_index);
-                }
-            }
-            softirq_index += 1;
-        }
-        cli();
+    pub fn raise_softirq(&self, softirq_num: SoftirqNumber) {
+        let mut flags = 0;
+        local_irq_save(&mut flags);
+        let processor_id = smp_get_processor_id() as usize;
+
+        cpu_pending(processor_id).insert(VecStatus::from(softirq_num));
+
+        compiler_fence(Ordering::SeqCst);
+
+        local_irq_restore(&flags);
+        // kdebug!("raise_softirq exited");
+    }
+    pub fn clear_softirq_pending(&self, softirq_num: SoftirqNumber) {
+        compiler_fence(Ordering::SeqCst);
+        cpu_pending(smp_get_processor_id() as usize).remove(VecStatus::from(softirq_num));
+        compiler_fence(Ordering::SeqCst);
     }
 }
+
+// ======= 以下为给C提供的接口 =======
+#[no_mangle]
+pub extern "C" fn rs_raise_softirq(softirq_num: u32) {
+    softirq_vectors().raise_softirq(SoftirqNumber::from(softirq_num as u64));
+}
+
+#[no_mangle]
+pub extern "C" fn rs_unregister_softirq(softirq_num: u32) {
+    softirq_vectors().unregister_softirq(SoftirqNumber::from(softirq_num as u64));
+}
+
+#[no_mangle]
+pub extern "C" fn rs_do_softirq() {
+    softirq_vectors().do_softirq();
+}
+
+#[no_mangle]
+pub extern "C" fn rs_clear_softirq_pending(softirq_num: u32) {
+    softirq_vectors().clear_softirq_pending(SoftirqNumber::from(softirq_num as u64));
+}

+ 2 - 1
kernel/src/include/bindings/wrapper.h

@@ -32,6 +32,7 @@
 #include <driver/disk/ahci/ahci.h>
 #include <driver/disk/ahci/ahci_rust.h>
 #include <driver/pci/pci.h>
+#include <driver/video/video.h>
 #include <driver/virtio/virtio.h>
 #include <include/DragonOS/refcount.h>
 #include <include/DragonOS/signal.h>
@@ -43,4 +44,4 @@
 #include <process/process.h>
 #include <sched/sched.h>
 #include <smp/smp.h>
-#include <time/sleep.h>
+#include <time/sleep.h>

+ 1 - 1
kernel/src/ktest/test-mutex.c

@@ -54,7 +54,7 @@ static long ktest_mutex_case1(uint64_t arg0, uint64_t arg1)
     // 启动另一个线程
     pid_t pid = kernel_thread(ktest_mutex_case1_pid1, 0, 0);
     // 等待100ms
-    usleep(100000);
+    rs_usleep(100000);
     while (list_empty(&mtx.wait_list))
         ;
 

+ 3 - 0
kernel/src/lib.rs

@@ -45,6 +45,9 @@ extern crate num_derive;
 extern crate smoltcp;
 extern crate thingbuf;
 
+#[cfg(target_arch = "x86_64")]
+extern crate x86;
+
 use mm::allocator::KernelAllocator;
 
 // <3>

+ 50 - 1
kernel/src/libs/spinlock.rs

@@ -9,6 +9,7 @@ use crate::arch::asm::irqflags::{local_irq_restore, local_irq_save};
 use crate::arch::interrupt::{cli, sti};
 use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t};
 use crate::process::preempt::{preempt_disable, preempt_enable};
+use crate::syscall::SystemError;
 
 /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁
 #[inline]
@@ -138,6 +139,19 @@ impl RawSpinlock {
         self.unlock();
         local_irq_restore(flags);
     }
+
+    /// @brief 尝试保存中断状态到flags中,关闭中断,并对自旋锁加锁
+    /// @return 加锁成功->true
+    ///         加锁失败->false
+    #[inline(always)]
+    pub fn try_lock_irqsave(&self, flags: &mut u64) -> bool {
+        local_irq_save(flags);
+        if self.try_lock() {
+            return true;
+        }
+        local_irq_restore(flags);
+        return false;
+    }
 }
 /// 实现了守卫的SpinLock, 能够支持内部可变性
 ///
@@ -154,6 +168,7 @@ pub struct SpinLock<T> {
 #[derive(Debug)]
 pub struct SpinLockGuard<'a, T: 'a> {
     lock: &'a SpinLock<T>,
+    flag: u64,
 }
 
 /// 向编译器保证,SpinLock在线程之间是安全的.
@@ -172,7 +187,41 @@ impl<T> SpinLock<T> {
     pub fn lock(&self) -> SpinLockGuard<T> {
         self.lock.lock();
         // 加锁成功,返回一个守卫
-        return SpinLockGuard { lock: self };
+        return SpinLockGuard {
+            lock: self,
+            flag: 0,
+        };
+    }
+
+    pub fn lock_irqsave(&self) -> SpinLockGuard<T> {
+        let mut flags: u64 = 0;
+        self.lock.lock_irqsave(&mut flags);
+        // 加锁成功,返回一个守卫
+        return SpinLockGuard {
+            lock: self,
+            flag: flags,
+        };
+    }
+
+    pub fn try_lock(&self) -> Result<SpinLockGuard<T>, SystemError> {
+        if self.lock.try_lock() {
+            return Ok(SpinLockGuard {
+                lock: self,
+                flag: 0,
+            });
+        }
+        return Err(SystemError::EAGAIN);
+    }
+
+    pub fn try_lock_irqsave(&self) -> Result<SpinLockGuard<T>, SystemError> {
+        let mut flags: u64 = 0;
+        if self.lock.try_lock_irqsave(&mut flags) {
+            return Ok(SpinLockGuard {
+                lock: self,
+                flag: flags,
+            });
+        }
+        return Err(SystemError::EAGAIN);
     }
 }
 

+ 4 - 2
kernel/src/main.c

@@ -37,6 +37,7 @@
 #include <driver/interrupt/apic/apic_timer.h>
 
 extern int rs_tty_init();
+extern void rs_softirq_init();
 
 ul bsp_idt_size, bsp_gdt_size;
 
@@ -118,7 +119,8 @@ void system_initialize()
     sched_init();
     irq_init();
 
-    softirq_init();
+    // softirq_init();
+    rs_softirq_init();
 
     current_pcb->cpu_id = 0;
     current_pcb->preempt_count = 0;
@@ -130,7 +132,7 @@ void system_initialize()
     // sched_init();
     io_mfence();
 
-    timer_init();
+    rs_timer_init();
     // 这里必须加内存屏障,否则会出错
     io_mfence();
     smp_init();

+ 9 - 1
kernel/src/mm/mod.rs

@@ -1,4 +1,4 @@
-use crate::include::bindings::bindings::PAGE_OFFSET;
+use crate::include::bindings::bindings::{PAGE_OFFSET, process_control_block, mm_struct};
 
 pub mod allocator;
 pub mod gfp;
@@ -15,3 +15,11 @@ pub fn virt_2_phys(addr: usize) -> usize {
 pub fn phys_2_virt(addr: usize) -> usize {
     addr + PAGE_OFFSET as usize
 }
+
+// ====== 重构内存管理后,请删除18-24行 ======
+//BUG pcb问题
+unsafe impl Send for process_control_block {}
+unsafe impl Sync for process_control_block {}
+
+unsafe impl Send for mm_struct {}
+unsafe impl Sync for mm_struct {}

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

@@ -275,7 +275,7 @@ int kthread_stop(struct process_control_block *pcb)
     // 等待指定的内核线程退出
     // todo: 使用completion机制改进这里
     while (target->exited == false)
-        usleep(5000);
+        rs_usleep(5000);
     retval = target->result;
 
     // 释放内核线程的页表

+ 5 - 5
kernel/src/sched/completion.c

@@ -92,7 +92,7 @@ static long __wait_for_common(struct completion *x, long (*action)(long), long t
 void wait_for_completion(struct completion *x)
 {
     spin_lock(&x->wait_queue.lock);
-    __wait_for_common(x, &schedule_timeout_ms, MAX_TIMEOUT, PROC_UNINTERRUPTIBLE);
+    __wait_for_common(x, &rs_schedule_timeout, MAX_TIMEOUT, PROC_UNINTERRUPTIBLE);
     spin_unlock(&x->wait_queue.lock);
 }
 
@@ -107,7 +107,7 @@ long wait_for_completion_timeout(struct completion *x, long timeout)
 {
     BUG_ON(timeout < 0);
     spin_lock(&x->wait_queue.lock);
-    timeout = __wait_for_common(x, &schedule_timeout_ms, timeout, PROC_UNINTERRUPTIBLE);
+    timeout = __wait_for_common(x, &rs_schedule_timeout, timeout, PROC_UNINTERRUPTIBLE);
     spin_unlock(&x->wait_queue.lock);
     return timeout;
 }
@@ -120,7 +120,7 @@ long wait_for_completion_timeout(struct completion *x, long timeout)
 void wait_for_completion_interruptible(struct completion *x)
 {
     spin_lock(&x->wait_queue.lock);
-    __wait_for_common(x, &schedule_timeout_ms, MAX_TIMEOUT, PROC_INTERRUPTIBLE);
+    __wait_for_common(x, &rs_schedule_timeout, MAX_TIMEOUT, PROC_INTERRUPTIBLE);
     spin_unlock(&x->wait_queue.lock);
 }
 
@@ -136,7 +136,7 @@ long wait_for_completion_interruptible_timeout(struct completion *x, long timeou
     BUG_ON(timeout < 0);
 
     spin_lock(&x->wait_queue.lock);
-    timeout = __wait_for_common(x, &schedule_timeout_ms, timeout, PROC_INTERRUPTIBLE);
+    timeout = __wait_for_common(x, &rs_schedule_timeout, timeout, PROC_INTERRUPTIBLE);
     spin_unlock(&x->wait_queue.lock);
     return timeout;
 }
@@ -257,7 +257,7 @@ int __test_completion_worker(void *input_data)
         wait_for_completion(data->one_to_many);
     }
 
-    schedule_timeout_ms(50);
+    rs_schedule_timeout(50);
     // for(uint64_t i=0;i<1e7;++i)
     //     pause();
     complete(data->one_to_one);

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

@@ -1,7 +1,7 @@
 /// @brief 获取当前的cpu id
 #[inline]
 pub fn smp_get_processor_id() -> u32 {
-    return crate::arch::cpu::current_cpu_id() as u32;
+    return crate::arch::cpu::current_cpu_id();
 }
 
 #[inline]

+ 1 - 1
kernel/src/syscall/syscall.c

@@ -378,7 +378,7 @@ uint64_t sys_nanosleep(struct pt_regs *regs)
     const struct timespec *rqtp = (const struct timespec *)regs->r8;
     struct timespec *rmtp = (struct timespec *)regs->r9;
 
-    return nanosleep(rqtp, rmtp);
+    return rs_nanosleep(rqtp, rmtp);
 }
 
 ul sys_ahci_end_req(struct pt_regs *regs)

+ 0 - 13
kernel/src/time/Makefile

@@ -1,13 +0,0 @@
-
-all: timer.o sleep.o
-
-CFLAGS += -I .
-
-timer.o: timer.c
-	$(CC) $(CFLAGS) -c timer.c -o timer.o
-
-sleep.o: sleep.c
-	$(CC) $(CFLAGS) -c sleep.c -o sleep.o
-
-clean:
-	echo "Done."

+ 3 - 1
kernel/src/time/mod.rs

@@ -1,4 +1,6 @@
+pub mod sleep;
 pub mod timekeep;
+pub mod timer;
 
 /// 表示时间的结构体
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
@@ -14,4 +16,4 @@ impl TimeSpec {
             tv_nsec: nsec,
         };
     }
-}
+}

+ 0 - 86
kernel/src/time/sleep.c

@@ -1,86 +0,0 @@
-#include "sleep.h"
-#include <common/errno.h>
-#include <time/timer.h>
-#include <process/process.h>
-#include <sched/sched.h>
-#include <mm/slab.h>
-#include <common/cpu.h>
-#include <common/glib.h>
-
-/**
- * @brief nanosleep定时事件到期后,唤醒指定的进程
- *
- * @param pcb 待唤醒的进程的pcb
- */
-void nanosleep_handler(void *pcb)
-{
-    process_wakeup((struct process_control_block *)pcb);
-}
-
-/**
- * @brief 休眠指定时间
- *
- * @param rqtp 指定休眠的时间
- * @param rmtp 返回的剩余休眠时间
- * @return int
- */
-int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
-{
-
-    if (rqtp->tv_nsec < 0 || rqtp->tv_nsec >= 1000000000)
-        return -EINVAL;
-
-
-    // 对于小于500us的时间,使用spin/rdtsc来进行定时
-    if (rqtp->tv_nsec < 500000)
-    {
-        uint64_t expired_tsc = rdtsc() + (((uint64_t)rqtp->tv_nsec) * Cpu_tsc_freq) / 1000000000;
-        while (rdtsc() < expired_tsc)
-            ;
-
-        if (rmtp != NULL)
-        {
-            rmtp->tv_nsec = 0;
-            rmtp->tv_sec = 0;
-        }
-        return 0;
-    }
-
-    // 增加定时任务
-    struct timer_func_list_t *sleep_task = (struct timer_func_list_t *)kmalloc(sizeof(struct timer_func_list_t), 0);
-    memset(sleep_task, 0, sizeof(struct timer_func_list_t));
-
-    timer_func_init_us(sleep_task, &nanosleep_handler, (void *)current_pcb, rqtp->tv_nsec / 1000);
-
-    timer_func_add(sleep_task);
-
-    current_pcb->state = PROC_INTERRUPTIBLE;
-    current_pcb->flags |= PF_NEED_SCHED;
-    sched();
-
-    // todo: 增加信号唤醒的功能后,设置rmtp
-
-    if (rmtp != NULL)
-    {
-        rmtp->tv_nsec = 0;
-        rmtp->tv_sec = 0;
-    }
-
-    return 0;
-}
-
-/**
- * @brief 睡眠指定时间
- *
- * @param usec 微秒
- * @return int
- */
-int usleep(useconds_t usec)
-{
-    struct timespec ts = {
-        tv_sec : (long int)(usec / 1000000),
-        tv_nsec : (long int)(usec % 1000000) * 1000UL
-    };
-
-    return nanosleep(&ts, NULL);
-}

+ 2 - 2
kernel/src/time/sleep.h

@@ -12,7 +12,7 @@
  * @param rmtp 返回的剩余休眠时间
  * @return int 
  */
-int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
+int rs_nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
 
 /**
  * @brief 睡眠指定时间
@@ -20,4 +20,4 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
  * @param usec 微秒
  * @return int
  */
-int usleep(useconds_t usec);
+int rs_usleep(useconds_t usec);

+ 139 - 0
kernel/src/time/sleep.rs

@@ -0,0 +1,139 @@
+use core::{arch::x86_64::_rdtsc, hint::spin_loop, ptr::null_mut};
+
+use alloc::{boxed::Box, sync::Arc};
+
+use crate::{
+    arch::{
+        asm::current::current_pcb,
+        interrupt::{cli, sti},
+        sched::sched,
+    },
+    include::bindings::bindings::{timespec, useconds_t, Cpu_tsc_freq},
+    syscall::SystemError,
+};
+
+use super::{
+    timer::{next_n_us_timer_jiffies, Timer, WakeUpHelper},
+    TimeSpec,
+};
+
+/// @brief 休眠指定时间(单位:纳秒)
+///
+/// @param sleep_time 指定休眠的时间
+///
+/// @return Ok(TimeSpec) 剩余休眠时间
+///
+/// @return Err(SystemError) 错误码
+pub fn nano_sleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
+    if sleep_time.tv_nsec < 0 || sleep_time.tv_nsec >= 1000000000 {
+        return Err(SystemError::EINVAL);
+    }
+    // 对于小于500us的时间,使用spin/rdtsc来进行定时
+
+    if sleep_time.tv_nsec < 500000 {
+        let expired_tsc: u64 =
+            unsafe { _rdtsc() + (sleep_time.tv_nsec as u64 * Cpu_tsc_freq) / 1000000000 };
+        while unsafe { _rdtsc() } < expired_tsc {
+            spin_loop()
+        }
+        return Ok(TimeSpec {
+            tv_sec: 0,
+            tv_nsec: 0,
+        });
+    }
+    // 创建定时器
+    let handler: Box<WakeUpHelper> = WakeUpHelper::new(current_pcb());
+    let timer: Arc<Timer> = Timer::new(
+        handler,
+        next_n_us_timer_jiffies((sleep_time.tv_nsec / 1000) as u64),
+    );
+
+    cli();
+    timer.activate();
+    unsafe {
+        current_pcb().mark_sleep_interruptible();
+    }
+    sti();
+
+    sched();
+
+    // TODO: 增加信号唤醒的功能后,返回正确的剩余时间
+
+    return Ok(TimeSpec {
+        tv_sec: 0,
+        tv_nsec: 0,
+    });
+}
+
+/// @brief 休眠指定时间(单位:微秒)
+///
+///  @param usec 微秒
+///
+/// @return Ok(TimeSpec) 剩余休眠时间
+///
+/// @return Err(SystemError) 错误码
+pub fn us_sleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
+    match nano_sleep(sleep_time) {
+        Ok(value) => return Ok(value),
+        Err(err) => return Err(err),
+    };
+}
+
+//===== 以下为提供给C的接口 =====
+
+/// @brief 休眠指定时间(单位:纳秒)(提供给C的接口)
+///
+/// @param sleep_time 指定休眠的时间
+///
+/// @param rm_time 剩余休眠时间(传出参数)
+///
+/// @return Ok(i32) 0
+///
+/// @return Err(SystemError) 错误码
+#[no_mangle]
+pub extern "C" fn rs_nanosleep(sleep_time: *const timespec, rm_time: *mut timespec) -> i32 {
+    if sleep_time == null_mut() {
+        return SystemError::EINVAL.to_posix_errno();
+    }
+    let slt_spec = TimeSpec {
+        tv_sec: unsafe { *sleep_time }.tv_sec,
+        tv_nsec: unsafe { *sleep_time }.tv_nsec,
+    };
+
+    match nano_sleep(slt_spec) {
+        Ok(value) => {
+            if rm_time != null_mut() {
+                unsafe { *rm_time }.tv_sec = value.tv_sec;
+                unsafe { *rm_time }.tv_nsec = value.tv_nsec;
+            }
+
+            return 0;
+        }
+        Err(err) => {
+            return err.to_posix_errno();
+        }
+    }
+}
+
+/// @brief 休眠指定时间(单位:微秒)(提供给C的接口)
+///
+///  @param usec 微秒
+///
+/// @return Ok(i32) 0
+///
+/// @return Err(SystemError) 错误码
+#[no_mangle]
+pub extern "C" fn rs_usleep(usec: useconds_t) -> i32 {
+    let sleep_time = TimeSpec {
+        tv_sec: (usec / 1000000) as i64,
+        tv_nsec: ((usec % 1000000) * 1000) as i64,
+    };
+    match us_sleep(sleep_time) {
+        Ok(_) => {
+            return 0;
+        }
+        Err(err) => {
+            return err.to_posix_errno();
+        }
+    };
+}

+ 0 - 178
kernel/src/time/timer.c

@@ -1,178 +0,0 @@
-#include "timer.h"
-#include <common/kprint.h>
-#include <driver/timers/HPET/HPET.h>
-#include <exception/softirq.h>
-#include <mm/slab.h>
-#include <process/process.h>
-#include <sched/sched.h>
-
-struct timer_func_list_t timer_func_head;
-static spinlock_t sched_lock;
-
-// 定时器循环阈值,每次最大执行20个定时器任务
-#define TIMER_RUN_CYCLE_THRESHOLD 20
-
-void test_timer()
-{
-    printk_color(ORANGE, BLACK, "(test_timer)");
-}
-
-void timer_init()
-{
-    spin_init(&sched_lock);
-
-    timer_jiffies = 0;
-    timer_func_init(&timer_func_head, NULL, NULL, -1UL);
-    register_softirq(TIMER_SIRQ, &do_timer_softirq, NULL);
-
-    struct timer_func_list_t *tmp = (struct timer_func_list_t *)kmalloc(sizeof(struct timer_func_list_t), 0);
-    timer_func_init(tmp, &test_timer, NULL, 5);
-    timer_func_add(tmp);
-
-    kdebug("timer func initialized.");
-}
-
-/**
- * @brief 处理时间软中断
- *
- * @param data
- */
-void do_timer_softirq(void *data)
-{
-    // todo: 修改这里以及 softirq 的部分,使得 timer 具有并行性
-    struct timer_func_list_t *tmp = container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list);
-    int cycle_count = 0;
-    while ((!list_empty(&timer_func_head.list)) && (tmp->expire_jiffies <= timer_jiffies))
-    {
-        spin_lock(&sched_lock);
-
-        timer_func_del(tmp);
-        tmp->func(tmp->data);
-        kfree(tmp);
-
-        spin_unlock(&sched_lock);
-
-        ++cycle_count;
-
-
-        // kdebug("SOLVE SOFT IRQ %d", cycle_count);
-
-        // 当前定时器达到阈值
-        if (cycle_count == TIMER_RUN_CYCLE_THRESHOLD)
-            break;
-        tmp = container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list);
-    }
-}
-
-/**
- * @brief 初始化定时功能
- *
- * @param timer_func 队列结构体
- * @param func 定时功能处理函数
- * @param data 传输的数据
- * @param expire_ms 定时时长(单位:ms)
- */
-void timer_func_init(struct timer_func_list_t *timer_func, void (*func)(void *data), void *data, uint64_t expire_ms)
-{
-    list_init(&timer_func->list);
-    timer_func->func = func;
-    timer_func->data = data;
-    timer_func->expire_jiffies = cal_next_n_ms_jiffies(expire_ms); // 设置过期的时间片
-}
-
-/**
- * @brief 初始化定时功能
- *
- * @param timer_func 队列结构体
- * @param func 定时功能处理函数
- * @param data 传输的数据
- * @param expire_us 定时时长(单位:us)
- */
-void timer_func_init_us(struct timer_func_list_t *timer_func, void (*func)(void *data), void *data, uint64_t expire_us)
-{
-    list_init(&timer_func->list);
-    timer_func->func = func;
-    timer_func->data = data;
-    timer_func->expire_jiffies = cal_next_n_us_jiffies(expire_us); // 设置过期的时间片
-    // kdebug("timer_func->expire_jiffies=%ld",cal_next_n_us_jiffies(expire_us));
-}
-
-/**
- * @brief 将定时功能添加到列表中
- *
- * @param timer_func 待添加的定时功能
- */
-void timer_func_add(struct timer_func_list_t *timer_func)
-{
-    struct timer_func_list_t *tmp = container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list);
-
-    if (list_empty(&timer_func_head.list) == false)
-        while (tmp->expire_jiffies < timer_func->expire_jiffies)
-            tmp = container_of(list_next(&tmp->list), struct timer_func_list_t, list);
-
-    list_add(&tmp->list, &(timer_func->list));
-}
-
-/**
- * @brief 将定时功能从列表中删除
- *
- * @param timer_func
- */
-void timer_func_del(struct timer_func_list_t *timer_func)
-{
-    list_del(&timer_func->list);
-}
-
-uint64_t sys_clock(struct pt_regs *regs)
-{
-    return timer_jiffies;
-}
-
-uint64_t clock()
-{
-    return timer_jiffies;
-}
-
-/**
- * @brief 辅助函数:传进schedule_timeout函数中, 然后时间一到就唤醒 pcb 指向的进程(即自身)
- *
- * @param pcb process_control_block
- */
-static void __wake_up_helper(void *pcb)
-{
-    BUG_ON(pcb == NULL);
-
-    BUG_ON(process_wakeup((struct process_control_block *)pcb) != 0); // 正常唤醒,返回值为0
-}
-
-/**
- * @brief 睡眠timeout的时间之后唤醒进程/线程
- *
- * @param timeout
- * @return long
- */
-long schedule_timeout_ms(long timeout)
-{
-    if (timeout == MAX_TIMEOUT) // 无期停止, 意味着不会调用func
-    {
-        sched();
-        return MAX_TIMEOUT;
-    }
-    else if (timeout < 0)
-    {
-        BUG_ON(1);
-        return 0;
-    }
-
-    spin_lock(&sched_lock);
-    struct timer_func_list_t timer={0}; 
-    timer_func_init(&timer, &__wake_up_helper, current_pcb, timeout);
-    timer_func_add(&timer);
-    current_pcb->state &= ~(PROC_RUNNING);
-    spin_unlock(&sched_lock);
-    sched();
-
-    timeout -= timer_jiffies;
-
-    return timeout < 0 ? 0 : timeout;
-}

+ 5 - 67
kernel/src/time/timer.h

@@ -3,74 +3,12 @@
 #include <common/glib.h>
 #include <driver/timers/HPET/HPET.h>
 
-
 // 定义LONG_MAX为最大超时时间 - 允许负数
 #define MAX_TIMEOUT (int64_t)((1ul << 63) - 1)
 
-uint64_t volatile timer_jiffies = 0; // 系统时钟计数
-
-// 计算接下来n毫秒对应的系统时间片
-#define cal_next_n_ms_jiffies(expire_ms) (timer_jiffies + 1000 * (expire_ms))
-// 计算接下来n微秒对应的系统时间片
-#define cal_next_n_us_jiffies(expire_us) (timer_jiffies + (expire_us))
-
-void timer_init();
-
-void do_timer_softirq(void *data);
-
-/**
- * @brief 定时功能队列
- *
- */
-struct timer_func_list_t
-{
-    struct List list;
-    uint64_t expire_jiffies;
-    void (*func)(void *data);
-    void *data;
-};
-
-extern struct timer_func_list_t timer_func_head;
-/**
- * @brief 初始化定时功能
- *
- * @param timer_func 队列结构体
- * @param func 定时功能处理函数
- * @param data 传输的数据
- * @param expire_ms 定时时长(单位:ms)
- */
-void timer_func_init(struct timer_func_list_t *timer_func, void (*func)(void *data), void *data, uint64_t expire_ms);
-
-/**
- * @brief 初始化定时功能
- *
- * @param timer_func 队列结构体
- * @param func 定时功能处理函数
- * @param data 传输的数据
- * @param expire_us 定时时长(单位:us)
- */
-void timer_func_init_us(struct timer_func_list_t *timer_func, void (*func)(void *data), void *data, uint64_t expire_us);
-
-/**
- * @brief 将定时功能添加到列表中
- *
- * @param timer_func 待添加的定时功能
- */
-void timer_func_add(struct timer_func_list_t *timer_func);
-
-/**
- * @brief 将定时功能从列表中删除
- *
- * @param timer_func
- */
-void timer_func_del(struct timer_func_list_t *timer_func);
-
-uint64_t clock();
+extern void rs_timer_init();
+extern int64_t rs_timer_get_first_expire();
+extern uint64_t rs_timer_next_n_ms_jiffies(uint64_t expire_ms);
+extern int64_t rs_schedule_timeout(int64_t timeout);
 
-/**
- * @brief 睡眠timeout的时间之后唤醒进程/线程
- * 
- * @param timeout 
- * @return long 
- */
-long schedule_timeout_ms(long timeout);
+extern uint64_t rs_clock();

+ 303 - 0
kernel/src/time/timer.rs

@@ -0,0 +1,303 @@
+use core::sync::atomic::{AtomicBool, Ordering};
+
+use alloc::{
+    boxed::Box,
+    collections::LinkedList,
+    sync::{Arc, Weak},
+};
+
+use crate::{
+    arch::{
+        asm::current::current_pcb,
+        interrupt::{cli, sti},
+        sched::sched,
+    },
+    exception::softirq::{softirq_vectors, SoftirqNumber, SoftirqVec},
+    include::bindings::bindings::{process_control_block, process_wakeup, pt_regs, PROC_RUNNING},
+    kdebug, kerror,
+    libs::spinlock::SpinLock,
+    syscall::SystemError,
+};
+
+const MAX_TIMEOUT: i64 = i64::MAX;
+const TIMER_RUN_CYCLE_THRESHOLD: usize = 20;
+static mut TIMER_JIFFIES: u64 = 0;
+
+lazy_static! {
+    pub static ref TIMER_LIST: SpinLock<LinkedList<Arc<Timer>>> = SpinLock::new(LinkedList::new());
+}
+
+/// 定时器要执行的函数的特征
+pub trait TimerFunction: Send + Sync {
+    fn run(&mut self);
+}
+
+/// WakeUpHelper函数对应的结构体
+pub struct WakeUpHelper {
+    pcb: &'static mut process_control_block,
+}
+
+impl WakeUpHelper {
+    pub fn new(pcb: &'static mut process_control_block) -> Box<WakeUpHelper> {
+        return Box::new(WakeUpHelper { pcb });
+    }
+}
+
+impl TimerFunction for WakeUpHelper {
+    fn run(&mut self) {
+        unsafe {
+            process_wakeup(self.pcb);
+        }
+    }
+}
+
+pub struct Timer(SpinLock<InnerTimer>);
+
+impl Timer {
+    /// @brief 创建一个定时器(单位:ms)
+    ///
+    /// @param timer_func 定时器需要执行的函数对应的结构体
+    ///
+    /// @param expire_jiffies 定时器结束时刻
+    ///
+    /// @return 定时器结构体
+    pub fn new(timer_func: Box<dyn TimerFunction>, expire_jiffies: u64) -> Arc<Self> {
+        let result: Arc<Timer> = Arc::new(Timer(SpinLock::new(InnerTimer {
+            expire_jiffies,
+            timer_func,
+            self_ref: Weak::default(),
+        })));
+
+        result.0.lock().self_ref = Arc::downgrade(&result);
+
+        return result;
+    }
+
+    /// @brief 将定时器插入到定时器链表中
+    pub fn activate(&self) {
+        let timer_list = &mut TIMER_LIST.lock();
+        let inner_guard = self.0.lock();
+        // 链表为空,则直接插入
+        if timer_list.is_empty() {
+            // FIXME push_timer
+            timer_list.push_back(inner_guard.self_ref.upgrade().unwrap());
+            return;
+        }
+
+        let mut split_pos: usize = 0;
+        for (pos, elt) in timer_list.iter().enumerate() {
+            if elt.0.lock().expire_jiffies > inner_guard.expire_jiffies {
+                split_pos = pos;
+                break;
+            }
+        }
+        let mut temp_list: LinkedList<Arc<Timer>> = timer_list.split_off(split_pos);
+        timer_list.push_back(inner_guard.self_ref.upgrade().unwrap());
+        timer_list.append(&mut temp_list);
+    }
+
+    #[inline]
+    fn run(&self) {
+        self.0.lock().timer_func.run();
+    }
+}
+
+/// 定时器类型
+pub struct InnerTimer {
+    /// 定时器结束时刻
+    pub expire_jiffies: u64,
+    /// 定时器需要执行的函数结构体
+    pub timer_func: Box<dyn TimerFunction>,
+    /// self_ref
+    self_ref: Weak<Timer>,
+}
+
+#[derive(Debug)]
+pub struct DoTimerSoftirq {
+    running: AtomicBool,
+}
+
+impl DoTimerSoftirq {
+    pub fn new() -> Self {
+        return DoTimerSoftirq {
+            running: AtomicBool::new(false),
+        };
+    }
+
+    fn set_run(&self) -> bool {
+        let x = self
+            .running
+            .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed);
+        if x.is_ok() {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    fn clear_run(&self) {
+        self.running.store(false, Ordering::Release);
+    }
+}
+impl SoftirqVec for DoTimerSoftirq {
+    fn run(&self) {
+        if self.set_run() == false {
+            return;
+        }
+        // 最多只处理TIMER_RUN_CYCLE_THRESHOLD个计时器
+        for _ in 0..TIMER_RUN_CYCLE_THRESHOLD {
+            // kdebug!("DoTimerSoftirq run");
+
+            let timer_list = &mut TIMER_LIST.lock();
+
+            if timer_list.is_empty() {
+                break;
+            }
+
+            if timer_list.front().unwrap().0.lock().expire_jiffies
+                <= unsafe { TIMER_JIFFIES as u64 }
+            {
+                let timer = timer_list.pop_front().unwrap();
+                drop(timer_list);
+                timer.run();
+            }
+        }
+
+        self.clear_run();
+    }
+}
+
+/// @brief 初始化timer模块
+pub fn timer_init() {
+    // FIXME 调用register_trap
+    let do_timer_softirq = Arc::new(DoTimerSoftirq::new());
+    softirq_vectors()
+        .register_softirq(SoftirqNumber::TIMER, do_timer_softirq)
+        .expect("Failed to register timer softirq");
+    kdebug!("timer initiated successfully");
+}
+
+/// 计算接下来n毫秒对应的定时器时间片
+pub fn next_n_ms_timer_jiffies(expire_ms: u64) -> u64 {
+    return unsafe { TIMER_JIFFIES as u64 } + 1000 * (expire_ms);
+}
+/// 计算接下来n微秒对应的定时器时间片
+pub fn next_n_us_timer_jiffies(expire_us: u64) -> u64 {
+    return unsafe { TIMER_JIFFIES as u64 } + (expire_us);
+}
+
+/// @brief 让pcb休眠timeout个jiffies
+///
+/// @param timeout 需要休眠的时间(单位:jiffies)
+///
+/// @return Ok(i64) 剩余需要休眠的时间(单位:jiffies)
+///
+/// @return Err(SystemError) 错误码
+pub fn schedule_timeout(mut timeout: i64) -> Result<i64, SystemError> {
+    // kdebug!("schedule_timeout");
+    if timeout == MAX_TIMEOUT {
+        sched();
+        return Ok(MAX_TIMEOUT);
+    } else if timeout < 0 {
+        kerror!("timeout can't less than 0");
+        return Err(SystemError::EINVAL);
+    } else {
+        // 禁用中断,防止在这段期间发生调度,造成死锁
+        cli();
+        timeout += unsafe { TIMER_JIFFIES } as i64;
+        let timer = Timer::new(WakeUpHelper::new(current_pcb()), timeout as u64);
+        timer.activate();
+        current_pcb().state &= (!PROC_RUNNING) as u64;
+        sti();
+
+        sched();
+        let time_remaining: i64 = timeout - unsafe { TIMER_JIFFIES } as i64;
+        if time_remaining >= 0 {
+            // 被提前唤醒,返回剩余时间
+            return Ok(time_remaining);
+        } else {
+            return Ok(0);
+        }
+    }
+}
+
+pub fn timer_get_first_expire() -> Result<u64, SystemError> {
+    // FIXME
+    // kdebug!("rs_timer_get_first_expire,timer_jif = {:?}", TIMER_JIFFIES);
+    for _ in 0..10 {
+        match TIMER_LIST.try_lock() {
+            Ok(timer_list) => {
+                // kdebug!("rs_timer_get_first_expire TIMER_LIST lock successfully");
+                if timer_list.is_empty() {
+                    // kdebug!("timer_list is empty");
+                    return Ok(0);
+                } else {
+                    // kdebug!("timer_list not empty");
+                    return Ok(timer_list.front().unwrap().0.lock().expire_jiffies);
+                }
+            }
+            // 加锁失败返回啥??
+            Err(_) => continue,
+        }
+    }
+    return Err(SystemError::EAGAIN);
+}
+
+pub fn update_timer_jiffies(add_jiffies: u64) -> u64 {
+    unsafe { TIMER_JIFFIES += add_jiffies };
+    return unsafe { TIMER_JIFFIES };
+}
+pub fn clock() -> u64 {
+    return unsafe { TIMER_JIFFIES };
+}
+// ====== 重构完成后请删掉extern C ======
+#[no_mangle]
+pub extern "C" fn rs_clock() -> u64 {
+    clock()
+}
+#[no_mangle]
+pub extern "C" fn sys_clock(_regs: *const pt_regs) -> u64 {
+    clock()
+}
+
+// ====== 以下为给C提供的接口 ======
+#[no_mangle]
+pub extern "C" fn rs_schedule_timeout(timeout: i64) -> i64 {
+    match schedule_timeout(timeout) {
+        Ok(v) => {
+            return v;
+        }
+        Err(e) => {
+            kdebug!("rs_schedule_timeout run failed");
+            return e.to_posix_errno() as i64;
+        }
+    }
+}
+
+#[no_mangle]
+pub extern "C" fn rs_timer_init() {
+    timer_init();
+}
+
+#[no_mangle]
+pub extern "C" fn rs_timer_next_n_ms_jiffies(expire_ms: u64) -> u64 {
+    return next_n_ms_timer_jiffies(expire_ms);
+}
+
+#[no_mangle]
+pub extern "C" fn rs_timer_next_n_us_jiffies(expire_us: u64) -> u64 {
+    return next_n_us_timer_jiffies(expire_us);
+}
+
+#[no_mangle]
+pub extern "C" fn rs_timer_get_first_expire() -> i64 {
+    match timer_get_first_expire() {
+        Ok(v) => return v as i64,
+        Err(e) => return e.to_posix_errno() as i64,
+    }
+}
+
+#[no_mangle]
+pub extern "C" fn rs_update_timer_jiffies(add_jiffies: u64) -> u64 {
+    return update_timer_jiffies(add_jiffies);
+}

+ 0 - 1
user/apps/about/about.c

@@ -1,5 +1,4 @@
 #include "sys_version.h" // 这是系统的版本头文件,在编译过程中自动生成
-#include <fcntl.h>
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>