diff --git a/src/context/context.rs b/src/context/context.rs index cb2eee035c6d18c8561f76d6d6143503243fbedc..1627b6efdb311c1a003c551eaed3f336c37171b2 100644 --- a/src/context/context.rs +++ b/src/context/context.rs @@ -10,7 +10,7 @@ use spin::Mutex; use crate::arch::{macros::InterruptStack, paging::PAGE_SIZE}; use crate::common::unique::Unique; use crate::context::arch; -use crate::context::file::FileDescriptor; +use crate::context::file::{FileDescriptor, FileDescription}; use crate::context::memory::{Grant, Memory, SharedMemory, Tls}; use crate::ipi::{ipi, IpiKind, IpiTarget}; use crate::scheme::{SchemeNamespace, FileHandle}; @@ -91,6 +91,76 @@ impl PartialEq for WaitpidKey { impl Eq for WaitpidKey {} +pub struct ContextSnapshot { + // Copy fields + pub id: ContextId, + pub pgid: ContextId, + pub ppid: ContextId, + pub ruid: u32, + pub rgid: u32, + pub rns: SchemeNamespace, + pub euid: u32, + pub egid: u32, + pub ens: SchemeNamespace, + pub sigmask: [u64; 2], + pub umask: usize, + pub status: Status, + pub status_reason: &'static str, + pub running: bool, + pub cpu_id: Option<usize>, + pub ticks: u64, + pub syscall: Option<(usize, usize, usize, usize, usize, usize)>, + // Clone fields + //TODO: is there a faster way than allocation? + pub name: Box<[u8]>, + pub files: Vec<Option<FileDescription>>, + // pub cwd: Box<[u8]>, +} + +impl ContextSnapshot { + //TODO: Should this accept &mut Context to ensure name/files will not change? + pub fn new(context: &Context) -> Self { + let name = context.name.lock().clone(); + let mut files = Vec::new(); + for descriptor_opt in context.files.lock().iter() { + let description = if let Some(descriptor) = descriptor_opt { + let description = descriptor.description.read(); + Some(FileDescription { + namespace: description.namespace, + scheme: description.scheme, + number: description.number, + flags: description.flags, + }) + } else { + None + }; + files.push(description); + } + + Self { + id: context.id, + pgid: context.pgid, + ppid: context.ppid, + ruid: context.ruid, + rgid: context.rgid, + rns: context.rns, + euid: context.euid, + egid: context.egid, + ens: context.ens, + sigmask: context.sigmask, + umask: context.umask, + status: context.status, + status_reason: context.status_reason, + running: context.running, + cpu_id: context.cpu_id, + ticks: context.ticks, + syscall: context.syscall, + name, + files, + } + } +} + /// A context, which identifies either a process or a thread #[derive(Debug)] pub struct Context { diff --git a/src/context/mod.rs b/src/context/mod.rs index b7024334dc8f27cd04c50015300cc148e53db8af..3d8b7ecedbab5f56b3e48c7946a735a8144ca936 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -6,7 +6,7 @@ use core::alloc::{GlobalAlloc, Layout}; use core::sync::atomic::Ordering; use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard}; -pub use self::context::{Context, ContextId, Status, WaitpidKey}; +pub use self::context::{Context, ContextId, ContextSnapshot, Status, WaitpidKey}; pub use self::list::ContextList; pub use self::switch::switch;