use mutex instead of static mut spinlocks

This commit is contained in:
Garen Tyler 2023-10-30 19:51:08 -06:00
parent d46c341aaf
commit 6d9a0a34e1
Signed by: garentyler
GPG Key ID: D7A048C454CB7054
4 changed files with 29 additions and 38 deletions

View File

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

View File

@ -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<bool> = 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();
}

View File

@ -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(),

View File

@ -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<usize> = 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.