From 6d9a0a34e157e576fc54da803a59803ccecbe335 Mon Sep 17 00:00:00 2001 From: Garen Tyler Date: Mon, 30 Oct 2023 19:51:08 -0600 Subject: [PATCH] use mutex instead of static mut spinlocks --- kernel/rustkernel/src/console/uart.rs | 7 +++---- kernel/rustkernel/src/lib.rs | 7 +++---- kernel/rustkernel/src/syscall.rs | 30 +++++++++++++-------------- kernel/rustkernel/src/trap.rs | 23 ++++++++------------ 4 files changed, 29 insertions(+), 38 deletions(-) diff --git a/kernel/rustkernel/src/console/uart.rs b/kernel/rustkernel/src/console/uart.rs index de3960d..d4e2a80 100644 --- a/kernel/rustkernel/src/console/uart.rs +++ b/kernel/rustkernel/src/console/uart.rs @@ -2,8 +2,7 @@ #![allow(non_upper_case_globals)] use crate::{ - console::consoleintr, proc::wakeup, queue::Queue, sync::mutex::Mutex, - trap::InterruptBlocker, + console::consoleintr, proc::wakeup, queue::Queue, sync::mutex::Mutex, trap::InterruptBlocker, }; use core::ptr::addr_of; @@ -111,7 +110,7 @@ impl Uart { pub fn write_byte(&self, b: u8) { let _ = InterruptBlocker::new(); - if unsafe { crate::PANICKED } { + if *crate::PANICKED.lock_spinning() { loop { core::hint::spin_loop(); } @@ -134,7 +133,7 @@ impl Uart { pub fn write_byte_buffered(&self, b: u8) { let mut buf = self.buffer.lock_spinning(); - if unsafe { crate::PANICKED } { + if *crate::PANICKED.lock_spinning() { loop { core::hint::spin_loop(); } diff --git a/kernel/rustkernel/src/lib.rs b/kernel/rustkernel/src/lib.rs index 62dbd4d..5986265 100644 --- a/kernel/rustkernel/src/lib.rs +++ b/kernel/rustkernel/src/lib.rs @@ -21,13 +21,13 @@ pub mod sync; pub mod syscall; pub mod trap; -use crate::proc::cpuid; +use crate::{proc::cpuid, sync::mutex::Mutex}; use core::ffi::{c_char, CStr}; pub(crate) use crate::console::printf::{print, println}; pub static mut STARTED: bool = false; -pub static mut PANICKED: bool = false; +pub static PANICKED: Mutex = Mutex::new(false); /// Maximum number of processes pub const NPROC: usize = 64; @@ -65,7 +65,6 @@ pub unsafe extern "C" fn main() -> ! { mem::virtual_memory::kvminit(); mem::virtual_memory::kvminithart(); proc::procinit(); - trap::trapinit(); trap::trapinithart(); riscv::plic::plicinit(); riscv::plic::plicinithart(); @@ -113,7 +112,7 @@ fn panic_wrapper(panic_info: &core::panic::PanicInfo) -> ! { println!("╚═╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝"); unsafe { - crate::PANICKED = true; + *crate::PANICKED.lock_spinning() = true; // Quit QEMU for convenience. crate::syscall::Syscall::Shutdown.call(); } diff --git a/kernel/rustkernel/src/syscall.rs b/kernel/rustkernel/src/syscall.rs index 833f56f..f21c15f 100644 --- a/kernel/rustkernel/src/syscall.rs +++ b/kernel/rustkernel/src/syscall.rs @@ -1,15 +1,17 @@ use crate::{ + mem::virtual_memory::{copyin, copyinstr}, println, - proc::{self, myproc, sleep_lock}, - riscv::{memlayout::QEMU_POWER, Pagetable}, + proc::{self, myproc}, + riscv::memlayout::QEMU_POWER, string::strlen, + trap::CLOCK_TICKS, +}; +use core::{ + mem::size_of, + ptr::{addr_of, addr_of_mut}, }; -use core::{mem::size_of, ptr::addr_of_mut}; extern "C" { - fn copyin(pagetable: Pagetable, dst: *mut u8, srcva: u64, len: u64) -> i32; - fn copyinstr(pagetable: Pagetable, dst: *mut u8, srcva: u64, len: u64) -> i32; - // fn syscall(); fn sys_pipe() -> u64; fn sys_read() -> u64; fn sys_exec() -> u64; @@ -87,26 +89,22 @@ impl Syscall { } } Syscall::Sleep => { - use crate::trap::{ticks, tickslock}; - let mut n = 0i32; argint(0, addr_of_mut!(n)); - let _guard = tickslock.lock(); - while ticks < ticks + n as u32 { + let mut ticks = CLOCK_TICKS.lock_spinning(); + + while *ticks < *ticks + n as usize { if proc::killed(myproc()) > 0 { - tickslock.unlock(); return -1i64 as u64; } - sleep_lock(addr_of_mut!(ticks).cast(), addr_of_mut!(tickslock).cast()) + // Sleep until the value changes. + ticks.sleep(addr_of!(CLOCK_TICKS).cast_mut().cast()); } 0 } // Returns how many clock tick interrupts have occured since start. - Syscall::Uptime => { - let _guard = crate::trap::tickslock.lock(); - crate::trap::ticks as u64 - } + Syscall::Uptime => *CLOCK_TICKS.lock_spinning() as u64, Syscall::Open => sys_open(), Syscall::Write => sys_write(), Syscall::Mknod => sys_mknod(), diff --git a/kernel/rustkernel/src/trap.rs b/kernel/rustkernel/src/trap.rs index 2c234af..0f8e86a 100644 --- a/kernel/rustkernel/src/trap.rs +++ b/kernel/rustkernel/src/trap.rs @@ -2,10 +2,10 @@ use crate::{ println, proc::{cpuid, exit, killed, mycpu, myproc, r#yield, setkilled, wakeup, ProcState}, riscv::*, - sync::spinlock::Spinlock, + sync::mutex::Mutex, syscall::syscall, }; -use core::ptr::{addr_of, addr_of_mut}; +use core::ptr::addr_of; extern "C" { pub fn kernelvec(); @@ -19,15 +19,7 @@ extern "C" { pub static mut userret: [u8; 0]; } -#[no_mangle] -pub static mut tickslock: Spinlock = Spinlock::new(); -#[no_mangle] -pub static mut ticks: u32 = 0; - -#[no_mangle] -pub unsafe extern "C" fn trapinit() { - tickslock = Spinlock::new(); -} +pub static CLOCK_TICKS: Mutex = Mutex::new(0); /// Set up to take exceptions and traps while in the kernel. #[no_mangle] @@ -37,9 +29,12 @@ pub unsafe extern "C" fn trapinithart() { #[no_mangle] pub unsafe extern "C" fn clockintr() { - let _guard = tickslock.lock(); - ticks += 1; - wakeup(addr_of_mut!(ticks).cast()); + let mut ticks = CLOCK_TICKS.lock_spinning(); + + *ticks += 1; + unsafe { + wakeup(addr_of!(CLOCK_TICKS).cast_mut().cast()); + } } /// Check if it's an external interrupt or software interrupt and handle it.