implement myproc as an associated function of the Proc struct
This commit is contained in:
parent
73e3ab9ebc
commit
0e753e8ba5
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user