Fix half of proc scheme errors.

This commit is contained in:
4lDO2
2024-07-08 20:44:10 +02:00
parent 89d1d49a4e
commit 89d532a267
13 changed files with 1111 additions and 979 deletions
+9
View File
@@ -93,6 +93,15 @@ macro_rules! int_like {
}
#[allow(dead_code)]
#[inline]
pub fn fetch_add(
&self,
with: $new_type_name,
order: ::core::sync::atomic::Ordering,
) -> $new_type_name {
$new_type_name::from(self.container.fetch_add(with.into(), order))
}
#[allow(dead_code)]
#[inline]
pub fn compare_exchange(
&self,
current: $new_type_name,
+3 -2
View File
@@ -26,7 +26,8 @@ use ::core::sync::atomic::AtomicUsize;
use super::{
empty_cr3,
memory::{AddrSpaceWrapper, GrantFileRef}, process::{Process, ProcessId},
memory::{AddrSpaceWrapper, GrantFileRef},
process::{Process, ProcessId},
};
int_like!(ContextId, AtomicContextId, usize, AtomicUsize);
@@ -65,7 +66,7 @@ pub enum HardBlockedReason {
AwaitingMmap { file_ref: GrantFileRef },
// TODO: PageFaultOom?
NotYetStarted,
// TODO: ptrace_stop?
PtraceStop,
}
#[derive(Copy, Clone, Debug)]
+13 -4
View File
@@ -5,10 +5,12 @@ use spinning_top::RwSpinlock;
use super::{
context::{Context, ContextId, Kstack},
memory::AddrSpaceWrapper, process::{Process, ProcessId},
memory::AddrSpaceWrapper,
process::{new_process, Process, ProcessId, ProcessInfo},
};
use crate::{
interrupt::InterruptStack,
scheme::SchemeNamespace,
syscall::error::{Error, Result, EAGAIN},
};
@@ -60,7 +62,10 @@ impl ContextList {
assert!(self
.map
// TODO
.insert(cid, Arc::new(RwSpinlock::new(Context::new(cid, pid, process)?)))
.insert(
cid,
Arc::new(RwSpinlock::new(Context::new(cid, pid, process)?))
)
.is_none());
Ok(self
@@ -70,7 +75,10 @@ impl ContextList {
}
/// Create a new context.
pub fn new_context(&mut self, process: Arc<RwLock<Process>>) -> 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.
@@ -102,11 +110,12 @@ impl ContextList {
pub fn spawn(
&mut self,
userspace_allowed: bool,
process: Arc<RwLock<Process>>,
func: extern "C" fn(),
) -> Result<&Arc<RwSpinlock<Context>>> {
let stack = Kstack::new()?;
let context_lock = self.new_context()?;
let context_lock = self.new_context(process)?;
{
let mut context = context_lock.write();
let _ = context.set_addr_space(Some(AddrSpaceWrapper::new()?));
+12 -3
View File
@@ -2,7 +2,7 @@
//!
//! For resources on contexts, please consult [wikipedia](https://en.wikipedia.org/wiki/Context_switch) and [osdev](https://wiki.osdev.org/Context_Switching)
use alloc::{borrow::Cow, sync::Arc};
use alloc::{borrow::Cow, sync::Arc, vec::Vec};
use spin::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use spinning_top::RwSpinlock;
@@ -11,10 +11,11 @@ use crate::{
cpu_set::LogicalCpuSet,
paging::{RmmA, RmmArch, TableKind},
percpu::PercpuBlock,
sync::WaitMap,
syscall::error::{Error, Result, ESRCH},
};
use self::process::ProcessId;
use self::process::{Process, ProcessId, ProcessInfo};
pub use self::{
context::{BorrowedHtBuf, Context, ContextId, Status, WaitpidKey},
list::ContextList,
@@ -73,8 +74,16 @@ pub use self::arch::empty_cr3;
pub fn init() {
let mut contexts = contexts_mut();
let id = ContextId::from(crate::cpu_id().get() as usize + 1);
let pid = ProcessId::new(0);
let process = Arc::new(RwLock::new(Process {
info: ProcessInfo::default(),
waitpid: Arc::new(WaitMap::new()),
threads: Vec::new(),
}));
let context_lock = contexts
.insert_context_raw(id)
.insert_context_raw(id, pid, process)
.expect("could not initialize first context");
let mut context = context_lock.write();
context.sched_affinity = LogicalCpuSet::empty();
+32 -11
View File
@@ -1,21 +1,28 @@
use core::ops::{Deref, DerefMut};
use core::{
ops::{Deref, DerefMut},
sync::atomic::{AtomicUsize, Ordering},
};
// TODO: move all this code to userspace
use alloc::collections::BTreeMap;
use alloc::sync::{Arc, Weak};
use alloc::vec::Vec;
use alloc::{
collections::BTreeMap,
sync::{Arc, Weak},
vec::Vec,
};
use spin::RwLock;
use spinning_top::RwSpinlock;
use syscall::{Error, Result, ESRCH};
use syscall::{Error, Result, ENOMEM, ESRCH};
use crate::scheme::{CallerCtx, SchemeNamespace};
use crate::sync::WaitMap;
use crate::{
scheme::{CallerCtx, SchemeNamespace},
sync::WaitMap,
};
use crate::context::{self, Context, WaitpidKey};
int_like!(ProcessId, usize);
int_like!(ProcessId, AtomicProcessId, usize, AtomicUsize);
#[derive(Debug)]
pub struct Process {
@@ -25,7 +32,7 @@ pub struct Process {
/// Threads of process
pub threads: Vec<Weak<RwSpinlock<Context>>>,
}
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, Default)]
pub struct ProcessInfo {
/// The process ID of this process
pub pid: ProcessId,
@@ -63,7 +70,10 @@ impl DerefMut for Process {
}
}
pub static PROCESSES: RwLock<BTreeMap<ProcessId, Arc<RwLock<Process>>>> = RwLock::new(BTreeMap::new());
pub const INIT: ProcessId = ProcessId::new(1);
static NEXT_PID: AtomicProcessId = AtomicProcessId::new(INIT);
pub static PROCESSES: RwLock<BTreeMap<ProcessId, Arc<RwLock<Process>>>> =
RwLock::new(BTreeMap::new());
/// Get an iterator of all parents
pub fn ancestors(
@@ -82,7 +92,9 @@ pub fn ancestors(
pub fn current() -> Result<Arc<RwLock<Process>>> {
let pid = context::current()?.read().pid;
Ok(Arc::clone(PROCESSES.read().get(&pid).ok_or(Error::new(ESRCH))?))
Ok(Arc::clone(
PROCESSES.read().get(&pid).ok_or(Error::new(ESRCH))?,
))
}
impl Process {
pub fn caller_ctx(&self) -> CallerCtx {
@@ -93,3 +105,12 @@ impl Process {
}
}
}
pub fn new_process(info: impl FnOnce(ProcessId) -> ProcessInfo) -> Result<Arc<RwLock<Process>>> {
let pid = NEXT_PID.fetch_add(ProcessId::new(1), Ordering::Relaxed);
Arc::try_new(RwLock::new(Process {
waitpid: Arc::try_new(WaitMap::new()).map_err(|_| Error::new(ENOMEM))?,
threads: Vec::new(),
info: info(pid),
}))
.map_err(|_| Error::new(ENOMEM))
}
+23 -2
View File
@@ -61,7 +61,13 @@ extern crate bitflags;
use core::sync::atomic::{AtomicU32, Ordering};
use crate::{context::switch::SwitchResult, scheme::SchemeNamespace};
use crate::{
context::{
process::{new_process, ProcessInfo, INIT},
switch::SwitchResult,
},
scheme::SchemeNamespace,
};
use crate::consts::*;
@@ -197,7 +203,22 @@ fn kmain(cpu_count: u32, bootstrap: Bootstrap) -> ! {
#[cfg(feature = "profiling")]
profiling::ready_for_profiling();
match context::contexts_mut().spawn(true, userspace_init) {
let process = new_process(|_| ProcessInfo {
pid: INIT,
ppid: INIT,
pgid: INIT,
session_id: INIT,
ruid: 0,
rgid: 0,
euid: 0,
egid: 0,
rns: SchemeNamespace::new(0),
ens: SchemeNamespace::new(0),
umask: 0o22,
})
.expect("failed to create init process");
match context::contexts_mut().spawn(true, process, userspace_init) {
Ok(context_lock) => {
let mut context = context_lock.write();
context.status = context::Status::Runnable;
+932 -929
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -1,7 +1,8 @@
use alloc::vec::Vec;
use crate::{
context::process, scheme,
context::process,
scheme,
syscall::error::{Error, Result},
};
+2 -1
View File
@@ -1,7 +1,8 @@
use alloc::vec::Vec;
use crate::{
context::process, scheme,
context::process,
scheme,
syscall::error::{Error, Result, ESRCH},
};
+6 -2
View File
@@ -21,10 +21,14 @@ use syscall::{
use crate::{
context::{
self, context::HardBlockedReason, file::{FileDescription, FileDescriptor, InternalFlags}, memory::{
self,
context::HardBlockedReason,
file::{FileDescription, FileDescriptor, InternalFlags},
memory::{
AddrSpace, AddrSpaceWrapper, BorrowedFmapSource, Grant, GrantFileRef, MmapMode,
PageSpan, DANGLING,
}, process, BorrowedHtBuf, Context, Status
},
process, BorrowedHtBuf, Context, Status,
},
event,
memory::Frame,
+10 -3
View File
@@ -7,7 +7,8 @@ use crate::{
context::{
self,
file::{FileDescription, FileDescriptor, InternalFlags},
memory::{AddrSpace, PageSpan}, process,
memory::{AddrSpace, PageSpan},
process,
},
paging::{Page, VirtualAddress, PAGE_SIZE},
scheme::{self, CallerCtx, FileHandle, KernelScheme, OpenResult},
@@ -169,7 +170,10 @@ pub fn close(fd: FileHandle) -> Result<()> {
fn duplicate_file(fd: FileHandle, user_buf: UserSliceRo) -> Result<FileDescriptor> {
let caller_ctx = process::current()?.read().caller_ctx();
let file = context::current()?.read().get_file(fd).ok_or(Error::new(EBADF))?;
let file = context::current()?
.read()
.get_file(fd)
.ok_or(Error::new(EBADF))?;
if user_buf.is_empty() {
Ok(FileDescriptor {
@@ -360,7 +364,10 @@ pub fn frename(fd: FileHandle, raw_path: UserSliceRo) -> Result<()> {
process.ens,
),
};
let file = context::current()?.read().get_file(fd).ok_or(Error::new(EBADF))?;
let file = context::current()?
.read()
.get_file(fd)
.ok_or(Error::new(EBADF))?;
/*
let mut path_buf = BorrowedHtBuf::head()?;
+3 -1
View File
@@ -236,7 +236,9 @@ pub fn syscall(
)?),
SYS_SETPGID => setpgid(ProcessId::from(b), ProcessId::from(c)).map(|()| 0),
SYS_SETREUID => setreuid(b as u32, c as u32).map(|()| 0),
SYS_SETRENS => setrens(SchemeNamespace::from(b), SchemeNamespace::from(c)).map(|()| 0),
SYS_SETRENS => {
setrens(SchemeNamespace::from(b), SchemeNamespace::from(c)).map(|()| 0)
}
SYS_SETREGID => setregid(b as u32, c as u32).map(|()| 0),
SYS_UMASK => umask(b),
SYS_VIRTTOPHYS => virttophys(b),
+64 -20
View File
@@ -6,7 +6,9 @@ use rmm::Arch;
use spin::RwLock;
use crate::context::{
memory::{AddrSpace, Grant, PageSpan}, process::{self, ProcessId, ProcessInfo}, WaitpidKey
memory::{AddrSpace, Grant, PageSpan},
process::{self, ProcessId, ProcessInfo},
WaitpidKey,
};
use crate::{
@@ -116,7 +118,12 @@ pub fn getpgid(pid: ProcessId) -> Result<ProcessId> {
let process_lock = if pid.get() == 0 {
process::current()?
} else {
Arc::clone(process::PROCESSES.read().get(&pid).ok_or(Error::new(ESRCH))?)
Arc::clone(
process::PROCESSES
.read()
.get(&pid)
.ok_or(Error::new(ESRCH))?,
)
};
let process = process_lock.read();
Ok(process.pgid)
@@ -254,7 +261,8 @@ pub fn kill(pid: ProcessId, sig: usize, parent_sigchld: bool) -> Result<usize> {
} => {
sent += 1;
let waitpid = Arc::clone(
&process::PROCESSES.read()
&process::PROCESSES
.read()
.get(&ppid)
.ok_or(Error::new(ESRCH))?
.read()
@@ -271,17 +279,19 @@ pub fn kill(pid: ProcessId, sig: usize, parent_sigchld: bool) -> Result<usize> {
}
SendResult::SucceededSigcont { ppid, pgid } => {
sent += 1;
&process::PROCESSES.read()
.get(&ppid)
.ok_or(Error::new(ESRCH))?
.read()
.waitpid.send(
WaitpidKey {
pid: Some(pid),
pgid: Some(pgid),
},
(pid, 0xffff),
);
&process::PROCESSES
.read()
.get(&ppid)
.ok_or(Error::new(ESRCH))?
.read()
.waitpid
.send(
WaitpidKey {
pid: Some(pid),
pgid: Some(pgid),
},
(pid, 0xffff),
);
}
}
Ok(())
@@ -293,7 +303,15 @@ pub fn kill(pid: ProcessId, sig: usize, parent_sigchld: bool) -> Result<usize> {
found += 1;
let (context_lock, info) = {
let process = process_lock.read();
(process.threads.first().ok_or(Error::new(ESRCH))?.upgrade().ok_or(Error::new(ESRCH))?, process.info)
(
process
.threads
.first()
.ok_or(Error::new(ESRCH))?
.upgrade()
.ok_or(Error::new(ESRCH))?,
process.info,
)
};
let mut context = context_lock.write();
let result = send(&mut *context, &info);
@@ -304,7 +322,15 @@ pub fn kill(pid: ProcessId, sig: usize, parent_sigchld: bool) -> Result<usize> {
for (pid, process_lock) in processes.iter() {
let (context_lock, info) = {
let process = process_lock.read();
(process.threads.first().ok_or(Error::new(ESRCH))?.upgrade().ok_or(Error::new(ESRCH))?, process.info)
(
process
.threads
.first()
.ok_or(Error::new(ESRCH))?
.upgrade()
.ok_or(Error::new(ESRCH))?,
process.info,
)
};
if info.pid.get() <= 2 {
@@ -328,7 +354,15 @@ pub fn kill(pid: ProcessId, sig: usize, parent_sigchld: bool) -> Result<usize> {
for (pid, process_lock) in processes.iter() {
let (context_lock, info) = {
let process = process_lock.read();
(process.threads.first().ok_or(Error::new(ESRCH))?.upgrade().ok_or(Error::new(ESRCH))?, process.info)
(
process
.threads
.first()
.ok_or(Error::new(ESRCH))?
.upgrade()
.ok_or(Error::new(ESRCH))?,
process.info,
)
};
if info.pgid != pgid {
@@ -404,14 +438,23 @@ pub fn umask(mask: usize) -> Result<usize> {
}
fn reap(pid: ProcessId) -> Result<ProcessId> {
let process_lock = Arc::clone(process::PROCESSES.read().get(&pid).ok_or(Error::new(ESRCH))?);
let process_lock = Arc::clone(
process::PROCESSES
.read()
.get(&pid)
.ok_or(Error::new(ESRCH))?,
);
// Spin until not running
loop {
// TODO: exit WaitCondition?
{
let mut process = process_lock.read();
if process.threads.iter().all(|t| t.upgrade().map_or(true, |t| !t.read().running)) {
if process
.threads
.iter()
.all(|t| t.upgrade().map_or(true, |t| !t.read().running))
{
break;
}
}
@@ -420,7 +463,8 @@ fn reap(pid: ProcessId) -> Result<ProcessId> {
interrupt::pause();
}
let _ = process::PROCESSES.write()
let _ = process::PROCESSES
.write()
.remove(&pid)
.ok_or(Error::new(ESRCH))?;