forkret
This commit is contained in:
parent
50b6016144
commit
d730a83b3e
@ -54,24 +54,3 @@ userinit(void)
|
||||
|
||||
release(&p->lock);
|
||||
}
|
||||
|
||||
// A fork child's very first scheduling by scheduler()
|
||||
// will swtch to forkret.
|
||||
void
|
||||
forkret(void)
|
||||
{
|
||||
static int first = 1;
|
||||
|
||||
// Still holding p->lock from scheduler.
|
||||
release(&myproc()->lock);
|
||||
|
||||
if (first) {
|
||||
// File system initialization must be run in the context of a
|
||||
// regular process (e.g., because it calls sleep), and thus cannot
|
||||
// be run from main().
|
||||
first = 0;
|
||||
fsinit(ROOTDEV);
|
||||
}
|
||||
|
||||
usertrapret();
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ pub unsafe fn devintr() -> i32 {
|
||||
|
||||
/// Return to user space
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn usertrapret() {
|
||||
pub unsafe extern "C" fn usertrapret() -> ! {
|
||||
let proc = Process::current().unwrap();
|
||||
|
||||
// We're about to switch the destination of traps from
|
||||
@ -147,7 +147,7 @@ pub unsafe extern "C" fn usertrapret() {
|
||||
TRAMPOLINE + (addr_of!(userret) as usize) - (addr_of!(trampoline) as usize);
|
||||
let trampoline_userret = trampoline_userret as *const ();
|
||||
// Rust's most dangerous function: core::mem::transmute
|
||||
let trampoline_userret = core::mem::transmute::<*const (), fn(u64)>(trampoline_userret);
|
||||
let trampoline_userret = core::mem::transmute::<*const (), fn(u64) -> !>(trampoline_userret);
|
||||
trampoline_userret(satp)
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Architecture-agnostic trap handling.
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
pub use super::riscv::trap::trapinithart as inithart;
|
||||
pub use super::riscv::trap::{trapinithart as inithart, usertrapret};
|
||||
|
||||
use super::interrupt;
|
||||
use crate::proc::cpu::Cpu;
|
||||
|
@ -83,6 +83,7 @@ pub struct DirectoryEntry {
|
||||
pub name: [u8; DIRSIZ],
|
||||
}
|
||||
|
||||
pub static mut FS_INITIALIZED: bool = false;
|
||||
extern "C" {
|
||||
pub fn fsinit(dev: i32);
|
||||
}
|
||||
|
@ -9,15 +9,17 @@ use super::{
|
||||
use crate::{
|
||||
arch::{
|
||||
mem::{kstack, Pagetable, PAGE_SIZE, PTE_R, PTE_W, PTE_X, TRAMPOLINE, TRAPFRAME},
|
||||
trap::InterruptBlocker,
|
||||
trap::{usertrapret, InterruptBlocker},
|
||||
virtual_memory::{
|
||||
copyout, mappages, uvmalloc, uvmcopy, uvmcreate, uvmdealloc, uvmfree, uvmunmap,
|
||||
},
|
||||
},
|
||||
fs::{
|
||||
file::{fileclose, filedup, File},
|
||||
fsinit,
|
||||
inode::{idup, iput, Inode},
|
||||
log::LogOperation,
|
||||
FS_INITIALIZED,
|
||||
},
|
||||
mem::{
|
||||
kalloc::{kalloc, kfree},
|
||||
@ -150,6 +152,9 @@ impl Process {
|
||||
pub fn is_current(&self) -> bool {
|
||||
addr_of!(*self).cast_mut() == Cpu::current().proc
|
||||
}
|
||||
pub fn is_initproc(&self) -> bool {
|
||||
addr_of!(*self).cast_mut() == unsafe { initproc }
|
||||
}
|
||||
|
||||
pub fn alloc_pid() -> i32 {
|
||||
NEXT_PID.fetch_add(1, Ordering::SeqCst)
|
||||
@ -200,7 +205,7 @@ impl Process {
|
||||
0,
|
||||
core::mem::size_of::<Context>() as u32,
|
||||
);
|
||||
p.context.ra = forkret as usize as u64;
|
||||
p.context.ra = Process::forkret as usize as u64;
|
||||
p.context.sp = p.kernel_stack + PAGE_SIZE as u64;
|
||||
|
||||
Ok(p)
|
||||
@ -340,6 +345,23 @@ impl Process {
|
||||
Ok(pid)
|
||||
}
|
||||
|
||||
/// A fork child's very first scheduling by
|
||||
/// scheduler() will swtch to forkret.
|
||||
pub unsafe fn forkret() -> ! {
|
||||
// Still holding p->lock from scheduler.
|
||||
Process::current().unwrap().lock.unlock();
|
||||
|
||||
if !FS_INITIALIZED {
|
||||
// File system initialization must be run in the context of a
|
||||
// regular process (e.g., because it calls sleep), and thus
|
||||
// cannot be run from main().
|
||||
FS_INITIALIZED = true;
|
||||
fsinit(crate::ROOTDEV as i32);
|
||||
}
|
||||
|
||||
usertrapret()
|
||||
}
|
||||
|
||||
/// Pass p's abandoned children to init.
|
||||
/// Caller must hold wait_lock.
|
||||
pub unsafe fn reparent(&self) {
|
||||
@ -355,7 +377,7 @@ impl Process {
|
||||
/// 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 {
|
||||
if self.is_initproc() {
|
||||
panic!("init exiting");
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user