use mutex instead of static mut spinlocks
This commit is contained in:
parent
d46c341aaf
commit
6d9a0a34e1
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user