Fix most code except proc scheme.
This commit is contained in:
+2
-10
@@ -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
@@ -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
@@ -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 {}
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user