implement myproc as an associated function of the Proc struct

This commit is contained in:
Garen Tyler 2023-11-03 18:31:07 -06:00
parent 73e3ab9ebc
commit 0e753e8ba5
Signed by: garentyler
GPG Key ID: D7A048C454CB7054
9 changed files with 129 additions and 88 deletions

View File

@ -13,7 +13,7 @@ pub mod uart;
use crate::{ use crate::{
fs::file::{devsw, CONSOLE}, fs::file::{devsw, CONSOLE},
proc::proc::{killed, myproc, procdump, wakeup}, proc::proc::{killed, procdump, wakeup, Proc},
sync::mutex::Mutex, sync::mutex::Mutex,
}; };
use core::{ffi::c_void, ptr::addr_of_mut}; use core::{ffi::c_void, ptr::addr_of_mut};
@ -114,7 +114,7 @@ pub fn consoleread(user_dst: i32, mut dst: u64, mut n: i32) -> i32 {
// Wait until interrupt handler has put // Wait until interrupt handler has put
// some input into cons.buffer. // some input into cons.buffer.
while console.read_index == console.write_index { while console.read_index == console.write_index {
if killed(myproc()) != 0 { if killed(addr_of_mut!(*Proc::current().unwrap())) != 0 {
// cons.lock.unlock(); // cons.lock.unlock();
return -1; return -1;
} }

View File

@ -4,7 +4,7 @@ use crate::{
fs::{log, stat::Stat}, fs::{log, stat::Stat},
io::pipe::Pipe, io::pipe::Pipe,
mem::virtual_memory::copyout, mem::virtual_memory::copyout,
proc::proc::myproc, proc::proc::Proc,
sync::{sleeplock::Sleeplock, spinlock::Spinlock}, sync::{sleeplock::Sleeplock, spinlock::Spinlock},
}; };
use core::ptr::{addr_of_mut, null_mut}; use core::ptr::{addr_of_mut, null_mut};
@ -206,7 +206,7 @@ pub unsafe extern "C" fn fileclose(file: *mut File) {
/// `addr` is a user virtual address, pointing to a Stat. /// `addr` is a user virtual address, pointing to a Stat.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn filestat(file: *mut File, addr: u64) -> i32 { pub unsafe extern "C" fn filestat(file: *mut File, addr: u64) -> i32 {
let p = myproc(); let proc = Proc::current().unwrap();
let mut stat = Stat::default(); let mut stat = Stat::default();
if (*file).kind == FileType::Inode || (*file).kind == FileType::Device { if (*file).kind == FileType::Inode || (*file).kind == FileType::Device {
@ -216,7 +216,7 @@ pub unsafe extern "C" fn filestat(file: *mut File, addr: u64) -> i32 {
} }
if copyout( if copyout(
(*p).pagetable, proc.pagetable,
addr, addr,
addr_of_mut!(stat).cast(), addr_of_mut!(stat).cast(),
core::mem::size_of::<Stat>() as u64, core::mem::size_of::<Stat>() as u64,

View File

@ -4,7 +4,7 @@ use crate::{
kalloc::{kalloc, kfree}, kalloc::{kalloc, kfree},
virtual_memory::{copyin, copyout}, virtual_memory::{copyin, copyout},
}, },
proc::proc::{killed, myproc, wakeup}, proc::proc::{killed, wakeup, Proc},
sync::spinlock::Spinlock, sync::spinlock::Spinlock,
}; };
use core::ptr::{addr_of, addr_of_mut}; use core::ptr::{addr_of, addr_of_mut};
@ -88,11 +88,11 @@ impl Pipe {
} }
pub unsafe fn write(&self, addr: u64, num_bytes: usize) -> Result<usize> { pub unsafe fn write(&self, addr: u64, num_bytes: usize) -> Result<usize> {
let mut i = 0; let mut i = 0;
let p = myproc(); let proc = Proc::current().unwrap();
let guard = self.lock.lock(); let guard = self.lock.lock();
while i < num_bytes { while i < num_bytes {
if self.is_read_open == 0 || killed(p) > 0 { if self.is_read_open == 0 || killed(addr_of_mut!(*proc)) > 0 {
return Err(PipeError::ProcessKilled); return Err(PipeError::ProcessKilled);
} }
if self.bytes_written == self.bytes_read + PIPESIZE as u32 { if self.bytes_written == self.bytes_read + PIPESIZE as u32 {
@ -101,7 +101,7 @@ impl Pipe {
guard.sleep(addr_of!(self.bytes_written).cast_mut().cast()); guard.sleep(addr_of!(self.bytes_written).cast_mut().cast());
} else { } else {
let mut b = 0u8; let mut b = 0u8;
if copyin((*p).pagetable, addr_of_mut!(b), addr + i as u64, 1) == -1 { if copyin(proc.pagetable, addr_of_mut!(b), addr + i as u64, 1) == -1 {
break; break;
} }
let index = self.bytes_written as usize % PIPESIZE; let index = self.bytes_written as usize % PIPESIZE;
@ -116,12 +116,12 @@ impl Pipe {
#[allow(clippy::while_immutable_condition)] #[allow(clippy::while_immutable_condition)]
pub unsafe fn read(&self, addr: u64, num_bytes: usize) -> Result<usize> { pub unsafe fn read(&self, addr: u64, num_bytes: usize) -> Result<usize> {
let mut i = 0; let mut i = 0;
let p = myproc(); let proc = Proc::current().unwrap();
let guard = self.lock.lock(); let guard = self.lock.lock();
// DOC: pipe-empty // DOC: pipe-empty
while self.bytes_read == self.bytes_written && self.is_write_open > 0 { while self.bytes_read == self.bytes_written && self.is_write_open > 0 {
if killed(p) > 0 { if killed(addr_of_mut!(*proc)) > 0 {
return Err(PipeError::ProcessKilled); return Err(PipeError::ProcessKilled);
} else { } else {
// DOC: piperead-sleep // DOC: piperead-sleep
@ -136,7 +136,7 @@ impl Pipe {
} }
let b = self.data[self.bytes_read as usize % PIPESIZE]; let b = self.data[self.bytes_read as usize % PIPESIZE];
self.as_mut().bytes_read += 1; self.as_mut().bytes_read += 1;
if copyout((*p).pagetable, addr + i as u64, addr_of!(b).cast_mut(), 1) == -1 { if copyout(proc.pagetable, addr + i as u64, addr_of!(b).cast_mut(), 1) == -1 {
break; break;
} }
i += 1; i += 1;

View File

@ -1,4 +1,5 @@
pub mod context; pub mod context;
pub mod cpu; pub mod cpu;
#[allow(clippy::module_inception)]
pub mod proc; pub mod proc;
pub mod trapframe; pub mod trapframe;

View File

@ -96,12 +96,45 @@ pub struct Proc {
/// Process name (debugging) /// Process name (debugging)
pub name: [c_char; 16], pub name: [c_char; 16],
} }
impl Proc {
pub const fn new() -> Proc {
Proc {
lock: Spinlock::new(),
state: ProcState::Unused,
chan: null_mut(),
killed: 0,
xstate: 0,
pid: 0,
parent: null_mut(),
kstack: 0,
sz: 0,
pagetable: null_mut(),
trapframe: null_mut(),
context: Context::new(),
ofile: [null_mut(); crate::NOFILE],
cwd: null_mut(),
name: [0x00; 16],
}
}
pub fn current() -> Option<&'static mut Proc> {
let _ = crate::trap::InterruptBlocker::new();
let p = Cpu::current().proc;
if p.is_null() {
None
} else {
unsafe { Some(&mut *p) }
}
}
}
/// Return the current struct proc *, or zero if none. /// Return the current struct proc *, or zero if none.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn myproc() -> *mut Proc { pub unsafe extern "C" fn myproc() -> *mut Proc {
let _ = crate::trap::InterruptBlocker::new(); if let Some(p) = Proc::current() {
Cpu::current().proc p as *mut Proc
} else {
null_mut()
}
} }
#[no_mangle] #[no_mangle]
@ -149,26 +182,26 @@ pub unsafe extern "C" fn reparent(p: *mut Proc) {
/// Grow or shrink user memory by n bytes. /// Grow or shrink user memory by n bytes.
/// Return 0 on success, -1 on failure. /// Return 0 on success, -1 on failure.
pub unsafe fn growproc(n: i32) -> i32 { pub unsafe fn growproc(n: i32) -> i32 {
let p = myproc(); let p = Proc::current().unwrap();
let mut sz = (*p).sz; let mut sz = p.sz;
if n > 0 { if n > 0 {
sz = uvmalloc((*p).pagetable, sz, sz.wrapping_add(n as u64), PTE_W); sz = uvmalloc(p.pagetable, sz, sz.wrapping_add(n as u64), PTE_W);
if sz == 0 { if sz == 0 {
return -1; return -1;
} }
} else if n < 0 { } else if n < 0 {
sz = uvmdealloc((*p).pagetable, sz, sz.wrapping_add(n as u64)); sz = uvmdealloc(p.pagetable, sz, sz.wrapping_add(n as u64));
} }
(*p).sz = sz; p.sz = sz;
0 0
} }
/// Give up the CPU for one scheduling round. /// Give up the CPU for one scheduling round.
pub unsafe fn r#yield() { pub unsafe fn r#yield() {
let p = myproc(); let p = Proc::current().unwrap();
let _guard = (*p).lock.lock(); let _guard = p.lock.lock();
(*p).state = ProcState::Runnable; p.state = ProcState::Runnable;
sched(); sched();
} }
@ -181,19 +214,19 @@ pub unsafe fn r#yield() {
/// there's no process. /// there's no process.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sched() { pub unsafe extern "C" fn sched() {
let p = myproc(); let p = Proc::current().unwrap();
let cpu = Cpu::current(); let cpu = Cpu::current();
if cpu.interrupt_disable_layers != 1 { if cpu.interrupt_disable_layers != 1 {
panic!("sched locks"); panic!("sched locks");
} else if (*p).state == ProcState::Running { } else if p.state == ProcState::Running {
panic!("sched running"); panic!("sched running");
} else if intr_get() > 0 { } else if intr_get() > 0 {
panic!("sched interruptible"); panic!("sched interruptible");
} }
let previous_interrupts_enabled = cpu.previous_interrupts_enabled; let previous_interrupts_enabled = cpu.previous_interrupts_enabled;
swtch(addr_of_mut!((*p).context), addr_of_mut!(cpu.context)); swtch(addr_of_mut!(p.context), addr_of_mut!(cpu.context));
cpu.previous_interrupts_enabled = previous_interrupts_enabled; cpu.previous_interrupts_enabled = previous_interrupts_enabled;
} }
@ -209,17 +242,17 @@ pub unsafe extern "C" fn sleep_lock(chan: *mut c_void, lock: *mut Spinlock) {
/// Sleep until `wakeup(chan)` is called somewhere else. /// Sleep until `wakeup(chan)` is called somewhere else.
pub unsafe fn sleep(chan: *mut c_void) { pub unsafe fn sleep(chan: *mut c_void) {
let p = myproc(); let p = Proc::current().unwrap();
let _guard = (*p).lock.lock(); let _guard = p.lock.lock();
// Go to sleep. // Go to sleep.
(*p).chan = chan; p.chan = chan;
(*p).state = ProcState::Sleeping; p.state = ProcState::Sleeping;
sched(); sched();
// Tidy up. // Tidy up.
(*p).chan = null_mut(); p.chan = null_mut();
} }
/// Kill the process with the given pid. /// Kill the process with the given pid.

View File

@ -1,5 +1,5 @@
use super::LockStrategy; use super::LockStrategy;
use crate::proc::proc::{myproc, sched, sleep, wakeup, ProcState}; use crate::proc::proc::{sched, sleep, wakeup, Proc, ProcState};
use core::{ use core::{
cell::UnsafeCell, cell::UnsafeCell,
ops::Drop, ops::Drop,
@ -83,18 +83,18 @@ impl<'l> LockGuard<'l> {
/// Sleep until `wakeup(chan)` is called somewhere /// Sleep until `wakeup(chan)` is called somewhere
/// else, yielding access to the lock until then. /// else, yielding access to the lock until then.
pub unsafe fn sleep(&self, chan: *mut core::ffi::c_void) { pub unsafe fn sleep(&self, chan: *mut core::ffi::c_void) {
let p = myproc(); let proc = Proc::current().unwrap();
let _guard = (*p).lock.lock(); let _guard = proc.lock.lock();
let strategy = self.lock.lock_strategy(); let strategy = self.lock.lock_strategy();
self.lock.unlock(); self.lock.unlock();
// Put the process to sleep. // Put the process to sleep.
(*p).chan = chan; proc.chan = chan;
(*p).state = ProcState::Sleeping; proc.state = ProcState::Sleeping;
sched(); sched();
// Tidy up and reacquire the lock. // Tidy up and reacquire the lock.
(*p).chan = null_mut(); proc.chan = null_mut();
self.lock.lock_unguarded(strategy); self.lock.lock_unguarded(strategy);
} }
} }

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
proc::proc::{myproc, sched, ProcState}, proc::proc::{sched, Proc, ProcState},
trap::{pop_intr_off, push_intr_off}, trap::{pop_intr_off, push_intr_off},
}; };
use core::{ use core::{
@ -46,17 +46,17 @@ pub struct SpinlockGuard<'l> {
impl<'l> SpinlockGuard<'l> { impl<'l> SpinlockGuard<'l> {
/// Sleep until `wakeup(chan)` is called somewhere else, yielding the lock until then. /// Sleep until `wakeup(chan)` is called somewhere else, yielding the lock until then.
pub unsafe fn sleep(&self, chan: *mut core::ffi::c_void) { pub unsafe fn sleep(&self, chan: *mut core::ffi::c_void) {
let p = myproc(); let proc = Proc::current().unwrap();
let _guard = (*p).lock.lock(); let _guard = proc.lock.lock();
self.lock.unlock(); self.lock.unlock();
// Put the process to sleep. // Put the process to sleep.
(*p).chan = chan; proc.chan = chan;
(*p).state = ProcState::Sleeping; proc.state = ProcState::Sleeping;
sched(); sched();
// Tidy up and reacquire the lock. // Tidy up and reacquire the lock.
(*p).chan = null_mut(); proc.chan = null_mut();
self.lock.lock_unguarded(); self.lock.lock_unguarded();
} }
} }

View File

@ -8,7 +8,7 @@ use crate::{
}, },
mem::virtual_memory::{copyin, copyinstr}, mem::virtual_memory::{copyin, copyinstr},
println, println,
proc::proc::{self, myproc}, proc::proc::{self, Proc},
string::strlen, string::strlen,
trap::CLOCK_TICKS, trap::CLOCK_TICKS,
NOFILE, NOFILE,
@ -102,7 +102,7 @@ impl Syscall {
} }
Syscall::Chdir => { Syscall::Chdir => {
let mut path = [0u8; crate::MAXPATH]; let mut path = [0u8; crate::MAXPATH];
let p = myproc(); let proc = Proc::current().unwrap();
let _operation = LogOperation::new(); let _operation = LogOperation::new();
@ -120,8 +120,8 @@ impl Syscall {
return -1i64 as u64; return -1i64 as u64;
} }
fs::iunlock(inode); fs::iunlock(inode);
fs::iput((*p).cwd); fs::iput(proc.cwd);
(*p).cwd = inode; proc.cwd = inode;
0 0
} }
Syscall::Dup => { Syscall::Dup => {
@ -138,11 +138,11 @@ impl Syscall {
file::filedup(file); file::filedup(file);
file_descriptor as u64 file_descriptor as u64
} }
Syscall::Getpid => (*myproc()).pid as u64, Syscall::Getpid => Proc::current().unwrap().pid as u64,
Syscall::Sbrk => { Syscall::Sbrk => {
let mut n = 0i32; let mut n = 0i32;
argint(0, addr_of_mut!(n)); argint(0, addr_of_mut!(n));
let addr = (*myproc()).sz; let addr = Proc::current().unwrap().sz;
if proc::growproc(n) < 0 { if proc::growproc(n) < 0 {
-1i64 as u64 -1i64 as u64
@ -157,7 +157,7 @@ impl Syscall {
let mut ticks = CLOCK_TICKS.lock_spinning(); let mut ticks = CLOCK_TICKS.lock_spinning();
while *ticks < *ticks + n as usize { while *ticks < *ticks + n as usize {
if proc::killed(myproc()) > 0 { if proc::killed(addr_of!(*Proc::current().unwrap()).cast_mut()) > 0 {
return -1i64 as u64; return -1i64 as u64;
} }
// Sleep until the value changes. // Sleep until the value changes.
@ -191,7 +191,7 @@ impl Syscall {
let mut file: *mut File = null_mut(); let mut file: *mut File = null_mut();
if argfd(0, addr_of_mut!(file_descriptor), addr_of_mut!(file)) >= 0 { if argfd(0, addr_of_mut!(file_descriptor), addr_of_mut!(file)) >= 0 {
(*myproc()).ofile[file_descriptor as usize] = null_mut(); Proc::current().unwrap().ofile[file_descriptor as usize] = null_mut();
file::fileclose(file); file::fileclose(file);
0 0
} else { } else {
@ -269,13 +269,13 @@ impl From<Syscall> for usize {
/// Fetch the u64 at addr from the current process. /// Fetch the u64 at addr from the current process.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn fetchaddr(addr: u64, ip: *mut u64) -> i32 { pub unsafe extern "C" fn fetchaddr(addr: u64, ip: *mut u64) -> i32 {
let p = myproc(); let proc = Proc::current().unwrap();
// Both tests needed, in case of overflow. // Both tests needed, in case of overflow.
if addr >= (*p).sz if addr >= proc.sz
|| addr + size_of::<u64>() as u64 > (*p).sz || addr + size_of::<u64>() as u64 > proc.sz
|| copyin( || copyin(
(*p).pagetable, proc.pagetable,
ip.cast(), ip.cast(),
addr, addr,
size_of::<*mut u64>() as u64, size_of::<*mut u64>() as u64,
@ -292,8 +292,9 @@ pub unsafe extern "C" fn fetchaddr(addr: u64, ip: *mut u64) -> i32 {
/// Returns length of string, not including null, or -1 for error. /// Returns length of string, not including null, or -1 for error.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn fetchstr(addr: u64, buf: *mut u8, max: i32) -> i32 { pub unsafe extern "C" fn fetchstr(addr: u64, buf: *mut u8, max: i32) -> i32 {
let p = myproc(); let proc = Proc::current().unwrap();
if copyinstr((*p).pagetable, buf, addr, max as u64) < 0 {
if copyinstr(proc.pagetable, buf, addr, max as u64) < 0 {
-1 -1
} else { } else {
strlen(buf.cast()) strlen(buf.cast())
@ -303,10 +304,11 @@ pub unsafe extern "C" fn fetchstr(addr: u64, buf: *mut u8, max: i32) -> i32 {
/// Allocate a file descriptor for the given file. /// Allocate a file descriptor for the given file.
/// Takes over file reference from caller on success. /// Takes over file reference from caller on success.
unsafe fn fdalloc(file: *mut File) -> Result<usize, ()> { unsafe fn fdalloc(file: *mut File) -> Result<usize, ()> {
let p = myproc(); let proc = Proc::current().unwrap();
for file_descriptor in 0..crate::NOFILE { for file_descriptor in 0..crate::NOFILE {
if (*p).ofile[file_descriptor].is_null() { if proc.ofile[file_descriptor].is_null() {
(*p).ofile[file_descriptor] = file; proc.ofile[file_descriptor] = file;
return Ok(file_descriptor); return Ok(file_descriptor);
} }
} }
@ -314,14 +316,15 @@ unsafe fn fdalloc(file: *mut File) -> Result<usize, ()> {
} }
unsafe fn argraw(argument_index: usize) -> u64 { unsafe fn argraw(argument_index: usize) -> u64 {
let p = myproc(); let proc = Proc::current().unwrap();
match argument_index { match argument_index {
0 => (*(*p).trapframe).a0, 0 => (*proc.trapframe).a0,
1 => (*(*p).trapframe).a1, 1 => (*proc.trapframe).a1,
2 => (*(*p).trapframe).a2, 2 => (*proc.trapframe).a2,
3 => (*(*p).trapframe).a3, 3 => (*proc.trapframe).a3,
4 => (*(*p).trapframe).a4, 4 => (*proc.trapframe).a4,
5 => (*(*p).trapframe).a5, 5 => (*proc.trapframe).a5,
_ => panic!("argraw"), _ => panic!("argraw"),
} }
} }
@ -354,7 +357,7 @@ pub unsafe extern "C" fn argfd(
return -1; return -1;
} }
let file: *mut File = (*myproc()).ofile[file_descriptor]; let file: *mut File = Proc::current().unwrap().ofile[file_descriptor];
if file.is_null() { if file.is_null() {
return -1; return -1;
} }
@ -380,13 +383,14 @@ pub unsafe extern "C" fn argstr(n: i32, buf: *mut u8, max: i32) -> i32 {
} }
pub unsafe fn syscall() { pub unsafe fn syscall() {
let p = myproc(); let proc = Proc::current().unwrap();
let num = (*(*p).trapframe).a7;
(*(*p).trapframe).a0 = match TryInto::<Syscall>::try_into(num as usize) { let num = (*proc.trapframe).a7;
(*proc.trapframe).a0 = match TryInto::<Syscall>::try_into(num as usize) {
Ok(syscall) => syscall.call(), Ok(syscall) => syscall.call(),
Err(_) => { Err(_) => {
println!("{} unknown syscall {}", (*p).pid, num); println!("{} unknown syscall {}", proc.pid, num);
-1i64 as u64 -1i64 as u64
} }
}; };

View File

@ -3,12 +3,12 @@ use crate::{
println, println,
proc::{ proc::{
cpu::Cpu, cpu::Cpu,
proc::{exit, killed, myproc, r#yield, setkilled, wakeup, ProcState}, proc::{exit, killed, r#yield, setkilled, wakeup, Proc, ProcState},
}, },
sync::mutex::Mutex, sync::mutex::Mutex,
syscall::syscall, syscall::syscall,
}; };
use core::ptr::addr_of; use core::ptr::{addr_of, addr_of_mut};
extern "C" { extern "C" {
pub fn kernelvec(); pub fn kernelvec();
@ -127,7 +127,7 @@ impl !Send for InterruptBlocker {}
/// Return to user space /// Return to user space
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn usertrapret() { pub unsafe extern "C" fn usertrapret() {
let p = myproc(); let proc = Proc::current().unwrap();
// We're about to switch the destination of traps from // We're about to switch the destination of traps from
// kerneltrap() to usertrap(), so turn off interrupts until // kerneltrap() to usertrap(), so turn off interrupts until
@ -142,12 +142,12 @@ pub unsafe extern "C" fn usertrapret() {
// Set up trapframe values that uservec will need when // Set up trapframe values that uservec will need when
// the process next traps into the kernel. // the process next traps into the kernel.
// kernel page table // kernel page table
(*(*p).trapframe).kernel_satp = r_satp(); (*proc.trapframe).kernel_satp = r_satp();
// process's kernel stack // process's kernel stack
(*(*p).trapframe).kernel_sp = (*p).kstack + PGSIZE; (*proc.trapframe).kernel_sp = proc.kstack + PGSIZE;
(*(*p).trapframe).kernel_trap = usertrap as usize as u64; (*proc.trapframe).kernel_trap = usertrap as usize as u64;
// hartid for Cpu::current_id() // hartid for Cpu::current_id()
(*(*p).trapframe).kernel_hartid = r_tp(); (*proc.trapframe).kernel_hartid = r_tp();
// Set up the registers that trampoline.S's // Set up the registers that trampoline.S's
// sret will use to get to user space. // sret will use to get to user space.
@ -161,10 +161,10 @@ pub unsafe extern "C" fn usertrapret() {
w_sstatus(x); w_sstatus(x);
// Set S Exception Program Counter to the saved user pc. // Set S Exception Program Counter to the saved user pc.
w_sepc((*(*p).trapframe).epc); w_sepc((*proc.trapframe).epc);
// Tell trampoline.S the user page table to switch to. // Tell trampoline.S the user page table to switch to.
let satp = make_satp((*p).pagetable); let satp = make_satp(proc.pagetable);
// Jump to userret in trampoline.S at the top of memory, which // Jump to userret in trampoline.S at the top of memory, which
// switches to the user page table, restores user registers, // switches to the user page table, restores user registers,
@ -195,7 +195,10 @@ pub unsafe extern "C" fn kerneltrap() {
if which_dev == 0 { if which_dev == 0 {
println!("scause {}\nsepc={} stval={}", scause, r_sepc(), r_stval()); println!("scause {}\nsepc={} stval={}", scause, r_sepc(), r_stval());
panic!("kerneltrap"); panic!("kerneltrap");
} else if which_dev == 2 && !myproc().is_null() && (*myproc()).state == ProcState::Running { } else if which_dev == 2
&& Proc::current().is_some()
&& Proc::current().unwrap().state == ProcState::Running
{
// Give up the CPU if this is a timer interrupt. // Give up the CPU if this is a timer interrupt.
r#yield(); r#yield();
} }
@ -219,21 +222,21 @@ pub unsafe extern "C" fn usertrap() {
// since we're now in the kernel. // since we're now in the kernel.
w_stvec(kernelvec as usize as u64); w_stvec(kernelvec as usize as u64);
let p = myproc(); let proc = Proc::current().unwrap();
// Save user program counter. // Save user program counter.
(*(*p).trapframe).epc = r_sepc(); (*proc.trapframe).epc = r_sepc();
if r_scause() == 8 { if r_scause() == 8 {
// System call // System call
if killed(p) > 0 { if killed(addr_of_mut!(*proc)) > 0 {
exit(-1); exit(-1);
} }
// sepc points to the ecall instruction, but // sepc points to the ecall instruction, but
// we want to return to the next instruction. // we want to return to the next instruction.
(*(*p).trapframe).epc += 4; (*proc.trapframe).epc += 4;
// An interrupt will change sepc, scause, and sstatus, // An interrupt will change sepc, scause, and sstatus,
// so enable only now that we're done with those registers. // so enable only now that we're done with those registers.
@ -247,14 +250,14 @@ pub unsafe extern "C" fn usertrap() {
println!( println!(
"usertrap(): unexpected scause {} {}\n\tsepc={} stval={}", "usertrap(): unexpected scause {} {}\n\tsepc={} stval={}",
r_scause(), r_scause(),
(*p).pid, proc.pid,
r_sepc(), r_sepc(),
r_stval() r_stval()
); );
setkilled(p); setkilled(addr_of_mut!(*proc));
} }
if killed(p) > 0 { if killed(addr_of_mut!(*proc)) > 0 {
exit(-1); exit(-1);
} }