WIP: continue the process transition

This commit is contained in:
4lDO2
2024-07-08 16:02:46 +02:00
parent 0da2fce64a
commit 8f452b0b0f
10 changed files with 268 additions and 254 deletions
+8 -45
View File
@@ -27,7 +27,7 @@ use ::core::sync::atomic::AtomicUsize;
use super::{
empty_cr3,
memory::{AddrSpaceWrapper, GrantFileRef},
memory::{AddrSpaceWrapper, GrantFileRef}, process::{Process, ProcessId},
};
int_like!(ContextId, AtomicContextId, usize, AtomicUsize);
@@ -71,8 +71,8 @@ pub enum HardBlockedReason {
#[derive(Copy, Clone, Debug)]
pub struct WaitpidKey {
pub pid: Option<ContextId>,
pub pgid: Option<ContextId>,
pub pid: Option<ProcessId>,
pub pgid: Option<ProcessId>,
}
impl Ord for WaitpidKey {
@@ -134,31 +134,11 @@ pub struct Context {
/// The internal context ID of this context
pub cid: ContextId,
/// The process ID of this context
pub pid: ContextId,
/// The group ID of this context
pub pgid: ContextId,
/// The ID of the parent context
pub ppid: ContextId,
/// The ID of the session
pub session_id: ContextId,
/// The real user id
pub ruid: u32,
/// The real group id
pub rgid: u32,
/// The real namespace id
pub rns: SchemeNamespace,
/// The effective user id
pub euid: u32,
/// The effective group id
pub egid: u32,
/// The effective namespace id
pub ens: SchemeNamespace,
pub pid: ProcessId,
/// Process state shared with other threads
pub process: Arc<RwLock<Process>>,
/// Signal handler
pub sig: Option<SignalState>,
/// Process umask
pub umask: usize,
/// Status of context
pub status: Status,
pub status_reason: &'static str,
@@ -186,8 +166,6 @@ pub struct Context {
/// Tail buffer to use when system call buffers are not page aligned
// TODO: Store in user memory?
pub syscall_tail: Option<RaiiFrame>,
/// Context is being waited on
pub waitpid: Arc<WaitMap<WaitpidKey, (ContextId, usize)>>,
/// Context should wake up at specified time
pub wake: Option<u128>,
/// The architecture specific context
@@ -209,10 +187,6 @@ pub struct Context {
/// All contexts except kmain will primarily live in userspace, and enter the kernel only when
/// interrupts or syscalls occur. This flag is set for all contexts but kmain.
pub userspace: bool,
/// A somewhat hacky way to initially stop a context when creating
/// a new instance of the proc: scheme, entirely separate from
/// signals or any other way to restart a process.
pub ptrace_stop: bool,
pub being_sigkilled: bool,
pub fmap_ret: Option<Frame>,
}
@@ -233,21 +207,12 @@ pub struct SignalState {
}
impl Context {
pub fn new(cid: ContextId, pid: ContextId) -> Result<Context> {
pub fn new(cid: ContextId, pid: ContextId, process: Arc<RwLock<Process>>) -> Result<Context> {
let this = Context {
cid,
pid,
pgid: pid,
ppid: ContextId::from(0),
session_id: ContextId::from(0),
ruid: 0,
rgid: 0,
rns: SchemeNamespace::from(0),
euid: 0,
egid: 0,
ens: SchemeNamespace::from(0),
process,
sig: None,
umask: 0o022,
status: Status::HardBlocked {
reason: HardBlockedReason::NotYetStarted,
},
@@ -260,7 +225,6 @@ impl Context {
inside_syscall: false,
syscall_head: Some(RaiiFrame::allocate()?),
syscall_tail: Some(RaiiFrame::allocate()?),
waitpid: Arc::new(WaitMap::new()),
wake: None,
arch: arch::Context::new(),
kfx: AlignedBox::<[u8], { arch::KFX_ALIGN }>::try_zeroed_slice(crate::arch::kfx_size())?,
@@ -269,7 +233,6 @@ impl Context {
name: Cow::Borrowed(""),
files: Arc::new(RwLock::new(Vec::new())),
userspace: false,
ptrace_stop: false,
fmap_ret: None,
being_sigkilled: false,
-15
View File
@@ -33,21 +33,6 @@ impl ContextList {
self.map.get(&id)
}
/// Get an iterator of all parents
pub fn ancestors(
&'_ self,
id: ContextId,
) -> impl Iterator<Item = (ContextId, &Arc<RwSpinlock<Context>>)> + '_ {
iter::successors(
self.get(id).map(|context| (id, context)),
move |(_id, context)| {
let context = context.read();
let id = context.ppid;
self.get(id).map(|context| (id, context))
},
)
}
/// Get the current context.
pub fn current(&self) -> Option<&Arc<RwSpinlock<Context>>> {
self.map.get(&super::current_cid())
+7
View File
@@ -14,6 +14,7 @@ use crate::{
syscall::error::{Error, Result, ESRCH},
};
use self::process::ProcessId;
pub use self::{
context::{BorrowedHtBuf, Context, ContextId, Status, WaitpidKey},
list::ContextList,
@@ -47,6 +48,9 @@ pub mod file;
/// Memory struct - contains a set of pages for a context
pub mod memory;
/// Process handling - TODO move to userspace
pub mod process;
/// Signal handling
pub mod signal;
@@ -103,6 +107,9 @@ pub fn contexts_mut() -> RwLockWriteGuard<'static, ContextList> {
pub fn current_cid() -> ContextId {
PercpuBlock::current().switch_internals.current_cid()
}
pub fn current_pid() -> Result<ProcessId> {
Ok(current()?.read().pid)
}
pub fn current() -> Result<Arc<RwSpinlock<Context>>> {
contexts()
+84
View File
@@ -0,0 +1,84 @@
// TODO: move all this code to userspace
use alloc::collections::BTreeMap;
use alloc::sync::{Arc, Weak};
use alloc::vec::Vec;
use spin::RwLock;
use spinning_top::RwSpinlock;
use syscall::{Error, Result, ESRCH};
use crate::scheme::SchemeNamespace;
use crate::sync::WaitMap;
use crate::context::{self, Context, WaitpidKey};
int_like!(ProcessId, usize);
#[derive(Debug)]
pub struct Process {
/// The process ID of this process
pub pid: ProcessId,
/// The group ID of this process
pub pgid: ProcessId,
/// The ID of the parent process
pub ppid: ProcessId,
/// The ID of the session
pub session_id: ProcessId,
/// The real user id
pub ruid: u32,
/// The real group id
pub rgid: u32,
/// The real namespace id
pub rns: SchemeNamespace,
/// The effective user id
pub euid: u32,
/// The effective group id
pub egid: u32,
/// The effective namespace id
pub ens: SchemeNamespace,
/// Process umask
pub umask: usize,
/// Context is being waited on
pub waitpid: WaitMap<WaitpidKey, (ProcessId, usize)>,
pub threads: Vec<Weak<RwSpinlock<Context>>>,
}
pub static PROCESSES: RwLock<BTreeMap<ProcessId, Arc<RwLock<Process>>>> = RwLock::new(BTreeMap::new());
/// Get an iterator of all parents
pub fn ancestors(
list: &BTreeSet<Process>,
id: ProcessId,
) -> impl Iterator<Item = (ProcessId, &Arc<RwSpinlock<Context>>)> + '_ {
core::iter::successors(
list.get(&id).map(|process| (id, process)),
move |(_id, process)| {
let context = process.read();
let id = process.ppid;
list.get(&id).map(|context| (id, context))
},
)
}
impl Ord for Process {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
Ord::cmp(&self.pid, &other.pid)
}
}
impl PartialOrd for Process {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
Some(Ord::cmp(&self.pid, &other.pid))
}
}
pub fn current() -> Result<Arc<RwLock<Process>>> {
let pid = context::current()?.read().pid;
PROCESSES.read().get(&pid).ok_or(Error::new(ESRCH))
}
impl PartialEq for Process {
fn eq(&self, other: &Self) -> bool {
Ord::cmp(self, other) == core::cmp::Ordering::Equal
}
}
impl Eq for Process {}
+3 -3
View File
@@ -131,7 +131,7 @@ pub fn switch() -> SwitchResult {
let mut skip_idle = true;
// Locate next context
for (pid, next_context_lock) in contexts
for (cid, next_context_lock) in contexts
// Include all contexts with IDs greater than the current...
.range((Bound::Excluded(prev_context_guard.cid), Bound::Unbounded))
.chain(
@@ -146,7 +146,7 @@ pub fn switch() -> SwitchResult {
)
// ... but not the current context, which is already locked
{
if pid == &idle_id && skip_idle {
if cid == &idle_id && skip_idle {
// Skip idle process the first time it shows up
skip_idle = false;
continue;
@@ -201,7 +201,7 @@ pub fn switch() -> SwitchResult {
}));
let (ptrace_session, ptrace_flags) = if let Some((session, bp)) = ptrace::sessions()
.get(&next_context.pid)
.get(&next_context.cid)
.map(|s| (Arc::downgrade(s), s.data.lock().breakpoint))
{
(Some(session), bp.map_or(PtraceFlags::empty(), |f| f.flags))