Fix most code except proc scheme.

This commit is contained in:
4lDO2
2024-07-08 19:01:21 +02:00
parent 8f452b0b0f
commit 89d1d49a4e
14 changed files with 161 additions and 179 deletions
+2 -10
View File
@@ -16,8 +16,7 @@ use crate::{
memory::{allocate_p2frame, deallocate_p2frame, Enomem, Frame, RaiiFrame},
paging::{RmmA, RmmArch},
percpu::PercpuBlock,
scheme::{CallerCtx, FileHandle, SchemeNamespace},
sync::WaitMap,
scheme::FileHandle,
};
use crate::syscall::error::{Error, Result, EAGAIN, ESRCH};
@@ -207,7 +206,7 @@ pub struct SignalState {
}
impl Context {
pub fn new(cid: ContextId, pid: ContextId, process: Arc<RwLock<Process>>) -> Result<Context> {
pub fn new(cid: ContextId, pid: ProcessId, process: Arc<RwLock<Process>>) -> Result<Context> {
let this = Context {
cid,
pid,
@@ -413,13 +412,6 @@ impl Context {
core::mem::replace(&mut self.addr_space, addr_space)
}
pub fn caller_ctx(&self) -> CallerCtx {
CallerCtx {
pid: self.pid.into(),
uid: self.euid,
gid: self.egid,
}
}
fn can_access_regs(&self) -> bool {
self.userspace
+11 -7
View File
@@ -1,11 +1,11 @@
use alloc::{collections::BTreeMap, sync::Arc};
use core::iter;
use spin::RwLock;
use spinning_top::RwSpinlock;
use super::{
context::{Context, ContextId, Kstack},
memory::AddrSpaceWrapper,
memory::AddrSpaceWrapper, process::{Process, ProcessId},
};
use crate::{
interrupt::InterruptStack,
@@ -53,22 +53,26 @@ impl ContextList {
pub(crate) fn insert_context_raw(
&mut self,
id: ContextId,
cid: ContextId,
pid: ProcessId,
process: Arc<RwLock<Process>>,
) -> Result<&Arc<RwSpinlock<Context>>> {
assert!(self
.map
// TODO
.insert(id, Arc::new(RwSpinlock::new(Context::new(id, id)?)))
.insert(cid, Arc::new(RwSpinlock::new(Context::new(cid, pid, process)?)))
.is_none());
Ok(self
.map
.get(&id)
.get(&cid)
.expect("Failed to insert new context. ID is out of bounds."))
}
/// Create a new context.
pub fn new_context(&mut self) -> Result<&Arc<RwSpinlock<Context>>> {
pub fn new_context(&mut self, process: Arc<RwLock<Process>>) -> Result<&Arc<RwSpinlock<Context>>> {
let pid = process.read().pid;
// Zero is not a valid context ID, therefore add 1.
//
// FIXME: Ensure the number of CPUs can't switch between new_context calls.
@@ -91,7 +95,7 @@ impl ContextList {
let id = ContextId::from(self.next_id);
self.next_id += 1;
self.insert_context_raw(id)
self.insert_context_raw(id, pid, process)
}
/// Spawn a context from a function.
+35 -24
View File
@@ -1,3 +1,5 @@
use core::ops::{Deref, DerefMut};
// TODO: move all this code to userspace
use alloc::collections::BTreeMap;
use alloc::sync::{Arc, Weak};
@@ -8,7 +10,7 @@ use spinning_top::RwSpinlock;
use syscall::{Error, Result, ESRCH};
use crate::scheme::SchemeNamespace;
use crate::scheme::{CallerCtx, SchemeNamespace};
use crate::sync::WaitMap;
use crate::context::{self, Context, WaitpidKey};
@@ -17,6 +19,14 @@ int_like!(ProcessId, usize);
#[derive(Debug)]
pub struct Process {
pub info: ProcessInfo,
/// Context is being waited on
pub waitpid: Arc<WaitMap<WaitpidKey, (ProcessId, usize)>>,
/// Threads of process
pub threads: Vec<Weak<RwSpinlock<Context>>>,
}
#[derive(Debug, Clone, Copy)]
pub struct ProcessInfo {
/// The process ID of this process
pub pid: ProcessId,
/// The group ID of this process
@@ -39,46 +49,47 @@ pub struct Process {
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>>>,
}
impl Deref for Process {
type Target = ProcessInfo;
fn deref(&self) -> &Self::Target {
&self.info
}
}
impl DerefMut for Process {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.info
}
}
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>,
list: &BTreeMap<ProcessId, Arc<RwLock<Process>>>,
id: ProcessId,
) -> impl Iterator<Item = (ProcessId, &Arc<RwSpinlock<Context>>)> + '_ {
) -> impl Iterator<Item = (ProcessId, &Arc<RwLock<Process>>)> + '_ {
core::iter::successors(
list.get(&id).map(|process| (id, process)),
move |(_id, process)| {
let context = process.read();
let process = process.read();
let id = process.ppid;
list.get(&id).map(|context| (id, context))
list.get(&id).map(|process| (id, process))
},
)
}
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))
Ok(Arc::clone(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 Process {
pub fn caller_ctx(&self) -> CallerCtx {
CallerCtx {
pid: self.pid.into(),
uid: self.euid,
gid: self.egid,
}
}
}
impl Eq for Process {}
+1 -7
View File
@@ -25,12 +25,6 @@ unsafe fn update_runnable(context: &mut Context, cpu_id: LogicalCpuId) -> Update
return UpdateResult::Skip;
}
// Ignore contexts stopped by ptrace
// TODO: ContextStatus::HardBlocked?
if context.ptrace_stop {
return UpdateResult::Skip;
}
// Ignore contexts assigned to other CPUs
if !context.sched_affinity.contains(cpu_id) {
return UpdateResult::Skip;
@@ -201,7 +195,7 @@ pub fn switch() -> SwitchResult {
}));
let (ptrace_session, ptrace_flags) = if let Some((session, bp)) = ptrace::sessions()
.get(&next_context.cid)
.get(&next_context.pid)
.map(|s| (Arc::downgrade(s), s.data.lock().breakpoint))
{
(Some(session), bp.map_or(PtraceFlags::empty(), |f| f.flags))