mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 08:53:29 +00:00
Use ParentProcess to cache parent pid
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
f01772ca85
commit
787604b7f6
@ -49,12 +49,13 @@ pub fn do_exit_group(term_status: TermStatus) {
|
|||||||
for (_, child_process) in current.children().lock().extract_if(|_, _| true) {
|
for (_, child_process) in current.children().lock().extract_if(|_, _| true) {
|
||||||
let mut parent = child_process.parent.lock();
|
let mut parent = child_process.parent.lock();
|
||||||
init_children.insert(child_process.pid(), child_process.clone());
|
init_children.insert(child_process.pid(), child_process.clone());
|
||||||
*parent = Arc::downgrade(&init_process);
|
parent.set_process(&init_process);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(parent) = current.parent() {
|
let parent = current.parent().lock().process();
|
||||||
|
if let Some(parent) = parent.upgrade() {
|
||||||
// Notify parent
|
// Notify parent
|
||||||
let signal = KernelSignal::new(SIGCHLD);
|
let signal = KernelSignal::new(SIGCHLD);
|
||||||
parent.enqueue_signal(signal);
|
parent.enqueue_signal(signal);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
use core::sync::atomic::Ordering;
|
||||||
|
|
||||||
use self::timer_manager::PosixTimerManager;
|
use self::timer_manager::PosixTimerManager;
|
||||||
use super::{
|
use super::{
|
||||||
posix_thread::PosixThreadExt,
|
posix_thread::PosixThreadExt,
|
||||||
@ -71,7 +73,7 @@ pub struct Process {
|
|||||||
/// Process status
|
/// Process status
|
||||||
status: ProcessStatus,
|
status: ProcessStatus,
|
||||||
/// Parent process
|
/// Parent process
|
||||||
pub(super) parent: Mutex<Weak<Process>>,
|
pub(super) parent: ParentProcess,
|
||||||
/// Children processes
|
/// Children processes
|
||||||
children: Mutex<BTreeMap<Pid, Arc<Process>>>,
|
children: Mutex<BTreeMap<Pid, Arc<Process>>>,
|
||||||
/// Process group
|
/// Process group
|
||||||
@ -102,6 +104,63 @@ pub struct Process {
|
|||||||
timer_manager: PosixTimerManager,
|
timer_manager: PosixTimerManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Representing a parent process by holding a weak reference to it and its PID.
|
||||||
|
///
|
||||||
|
/// This type caches the value of the PID so that it can be retrieved cheaply.
|
||||||
|
///
|
||||||
|
/// The benefit of using `ParentProcess` over `(Mutex<Weak<Process>>, Atomic<Pid>,)` is to
|
||||||
|
/// enforce the invariant that the cached PID and the weak reference are always kept in sync.
|
||||||
|
pub struct ParentProcess {
|
||||||
|
process: Mutex<Weak<Process>>,
|
||||||
|
pid: Atomic<Pid>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParentProcess {
|
||||||
|
pub fn new(process: Weak<Process>) -> Self {
|
||||||
|
let pid = match process.upgrade() {
|
||||||
|
Some(process) => process.pid(),
|
||||||
|
None => 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
Self {
|
||||||
|
process: Mutex::new(process),
|
||||||
|
pid: Atomic::new(pid),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pid(&self) -> Pid {
|
||||||
|
self.pid.load(Ordering::Relaxed)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lock(&self) -> ParentProcessGuard<'_> {
|
||||||
|
ParentProcessGuard {
|
||||||
|
guard: self.process.lock(),
|
||||||
|
this: self,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ParentProcessGuard<'a> {
|
||||||
|
guard: MutexGuard<'a, Weak<Process>>,
|
||||||
|
this: &'a ParentProcess,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParentProcessGuard<'_> {
|
||||||
|
pub fn process(&self) -> Weak<Process> {
|
||||||
|
self.guard.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pid(&self) -> Pid {
|
||||||
|
self.this.pid()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Update both pid and weak ref.
|
||||||
|
pub fn set_process(&mut self, new_process: &Arc<Process>) {
|
||||||
|
self.this.pid.store(new_process.pid(), Ordering::Relaxed);
|
||||||
|
*self.guard = Arc::downgrade(new_process);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Process {
|
impl Process {
|
||||||
/// Returns the current process.
|
/// Returns the current process.
|
||||||
///
|
///
|
||||||
@ -141,7 +200,7 @@ impl Process {
|
|||||||
process_vm,
|
process_vm,
|
||||||
children_pauser,
|
children_pauser,
|
||||||
status: ProcessStatus::new_uninit(),
|
status: ProcessStatus::new_uninit(),
|
||||||
parent: Mutex::new(parent),
|
parent: ParentProcess::new(parent),
|
||||||
children: Mutex::new(BTreeMap::new()),
|
children: Mutex::new(BTreeMap::new()),
|
||||||
process_group: Mutex::new(Weak::new()),
|
process_group: Mutex::new(Weak::new()),
|
||||||
file_table,
|
file_table,
|
||||||
@ -268,12 +327,12 @@ impl Process {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// *********** Parent and child ***********
|
// *********** Parent and child ***********
|
||||||
pub fn parent(&self) -> Option<Arc<Process>> {
|
pub fn parent(&self) -> &ParentProcess {
|
||||||
self.parent.lock().upgrade()
|
&self.parent
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_init_process(&self) -> bool {
|
pub fn is_init_process(&self) -> bool {
|
||||||
self.parent().is_none()
|
self.parent.lock().process().upgrade().is_none()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn children(&self) -> &Mutex<BTreeMap<Pid, Arc<Process>>> {
|
pub(super) fn children(&self) -> &Mutex<BTreeMap<Pid, Arc<Process>>> {
|
||||||
|
@ -4,9 +4,5 @@ use super::SyscallReturn;
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn sys_getppid(ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_getppid(ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let parent = ctx.process.parent();
|
Ok(SyscallReturn::Return(ctx.process.parent().pid() as _))
|
||||||
match parent {
|
|
||||||
None => Ok(SyscallReturn::Return(0)),
|
|
||||||
Some(parent) => Ok(SyscallReturn::Return(parent.pid() as _)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user