This commit is contained in:
Garen Tyler 2023-11-03 20:36:10 -06:00
parent badd35b3f9
commit a168c989cf
Signed by: garentyler
GPG Key ID: D7A048C454CB7054
4 changed files with 75 additions and 57 deletions

View File

@ -112,47 +112,7 @@ void reparent(struct proc *p);
// Exit the current process. Does not return.
// An exited process remains in the zombie state
// until its parent calls wait().
void
exit(int status)
{
struct proc *p = myproc();
if(p == initproc)
panic("init exiting");
// Close all open files.
for(int fd = 0; fd < NOFILE; fd++){
if(p->ofile[fd]){
struct file *f = p->ofile[fd];
fileclose(f);
p->ofile[fd] = 0;
}
}
begin_op();
iput(p->cwd);
end_op();
p->cwd = 0;
acquire(&wait_lock);
// Give any children to init.
reparent(p);
// Parent might be sleeping in wait().
wakeup(p->parent);
acquire(&p->lock);
p->xstate = status;
p->state = ZOMBIE;
release(&wait_lock);
// Jump into the scheduler, never to return.
sched();
panic("zombie exit");
}
void exit(int status);
// Wait for a child process to exit and return its pid.
// Return -1 if this process has no children.

View File

@ -1,9 +1,14 @@
#![allow(clippy::comparison_chain)]
use super::{context::Context, cpu::Cpu, scheduler::wakeup, trapframe::Trapframe};
use super::{context::Context, cpu::Cpu, scheduler::{wakeup, sched}, trapframe::Trapframe};
use crate::{
arch::riscv::{Pagetable, PTE_W, PTE_R, PTE_X, PGSIZE, memlayout::{TRAMPOLINE, TRAPFRAME}},
fs::{file::{File, Inode, filedup}, idup},
fs::{
file::{File, Inode, filedup, fileclose},
idup,
iput,
log::LogOperation,
},
mem::{
kalloc::{kfree, kalloc},
memset,
@ -11,6 +16,7 @@ use crate::{
},
sync::spinlock::Spinlock,
string::safestrcpy,
println,
};
use core::{
ffi::{c_char, c_void},
@ -35,7 +41,7 @@ extern "C" {
pub fn userinit();
pub fn forkret();
// pub fn fork() -> i32;
pub fn exit(status: i32) -> !;
// pub fn exit(status: i32) -> !;
pub fn wait(addr: u64) -> i32;
pub fn procdump();
pub fn proc_mapstacks(kpgtbl: Pagetable);
@ -299,6 +305,60 @@ impl Process {
Ok(pid)
}
/// Pass p's abandoned children to init.
/// Caller must hold wait_lock.
pub unsafe fn reparent(&self) {
for p in proc.iter_mut() {
if p.parent == addr_of!(*self).cast_mut() {
p.parent = initproc;
wakeup(initproc.cast());
}
}
}
/// Exit the current process. Does not return.
/// An exited process remains in the zombie state
/// until its parent calls wait().
pub unsafe fn exit(&mut self, status: i32) -> ! {
if addr_of_mut!(*self) == initproc {
panic!("init exiting");
}
// Close all open files.
for file in self.ofile.iter_mut() {
if !file.is_null() {
fileclose(*file);
*file = null_mut();
}
}
{
let _operation = LogOperation::new();
iput(self.cwd);
}
self.cwd = null_mut();
{
let _guard = wait_lock.lock();
// Give any children to init.
self.reparent();
// Parent might be sleeping in wait().
wakeup(self.parent.cast());
self.lock.lock_unguarded();
self.xstate = status;
self.state = ProcessState::Zombie;
}
// Jump into the scheduler, never to return.
sched();
loop {
unreachable!();
}
}
/// Kill the process with the given pid.
/// Returns true if the process was killed.
/// The victim won't exit until it tries to return
@ -376,16 +436,14 @@ pub unsafe extern "C" fn proc_freepagetable(pagetable: Pagetable, size: u64) {
Process::free_pagetable(pagetable, size as usize)
}
/// Pass p's abandoned children to init.
/// Caller must hold wait_lock.
#[no_mangle]
pub unsafe extern "C" fn reparent(p: *mut Process) {
for pp in proc.iter_mut().map(|p: &mut Process| addr_of_mut!(*p)) {
if (*pp).parent == p {
(*pp).parent = initproc;
wakeup(initproc.cast());
}
}
(*p).reparent()
}
#[no_mangle]
pub unsafe extern "C" fn exit(status: i32) -> ! {
Process::current().unwrap().exit(status)
}
/// Kill the process with the given pid.

View File

@ -59,9 +59,9 @@ impl Syscall {
match self {
Syscall::Fork => Process::fork().unwrap_or(-1) as i64 as u64,
Syscall::Exit => {
let mut n = 0i32;
argint(0, addr_of_mut!(n));
process::exit(n)
let mut status = 0i32;
argint(0, addr_of_mut!(status));
Process::current().unwrap().exit(status)
}
Syscall::Wait => {
let mut p = 0u64;

View File

@ -232,7 +232,7 @@ pub unsafe extern "C" fn usertrap() {
// System call
if proc.is_killed() {
exit(-1);
proc.exit(-1);
}
// sepc points to the ecall instruction, but
@ -259,7 +259,7 @@ pub unsafe extern "C" fn usertrap() {
}
if proc.is_killed() {
exit(-1);
proc.exit(-1);
}
// Give up the CPU if this is a timer interrupt.