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