From 3de7d1c82953675e79952f3da81a6d5fce985193 Mon Sep 17 00:00:00 2001 From: Garen Tyler Date: Fri, 3 Nov 2023 19:23:31 -0600 Subject: [PATCH] move growproc to assoc fn --- kernel/rustkernel/src/proc/process.rs | 49 ++++++++++++++++----------- kernel/rustkernel/src/syscall.rs | 9 ++--- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/kernel/rustkernel/src/proc/process.rs b/kernel/rustkernel/src/proc/process.rs index 28cbc6b..a0a281e 100644 --- a/kernel/rustkernel/src/proc/process.rs +++ b/kernel/rustkernel/src/proc/process.rs @@ -44,7 +44,7 @@ extern "C" { pub static NEXT_PID: AtomicI32 = AtomicI32::new(1); #[repr(C)] -#[derive(PartialEq, Default)] +#[derive(Copy, Clone, Debug, Default, PartialEq)] pub enum ProcessState { #[default] Unused, @@ -55,6 +55,11 @@ pub enum ProcessState { Zombie, } +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum ProcessError { + Allocation, +} + /// Per-process state. #[repr(C)] pub struct Process { @@ -124,6 +129,10 @@ impl Process { } } + pub fn alloc_pid() -> i32 { + NEXT_PID.fetch_add(1, Ordering::SeqCst) + } + /// Free a proc structure and the data hanging from it, including user pages. /// self.lock must be held. pub unsafe fn free(&mut self) { @@ -145,6 +154,24 @@ impl Process { self.state = ProcessState::Unused; } + /// Grow or shrink user memory. + pub unsafe fn grow_memory(&mut self, num_bytes: i32) -> Result<(), ProcessError> { + let mut size = self.sz; + + if num_bytes > 0 { + size = uvmalloc(self.pagetable, size, size.wrapping_add(num_bytes as u64), PTE_W); + + if size == 0 { + return Err(ProcessError::Allocation); + } + } else if num_bytes < 0 { + size = uvmdealloc(self.pagetable, size, size.wrapping_add(num_bytes as u64)); + } + + self.sz = size; + Ok(()) + } + /// Kill the process with the given pid. /// Returns true if the process was killed. /// The victim won't exit until it tries to return @@ -193,7 +220,7 @@ pub extern "C" fn myproc() -> *mut Process { #[no_mangle] pub extern "C" fn allocpid() -> i32 { - NEXT_PID.fetch_add(1, Ordering::SeqCst) + Process::alloc_pid() } /// Free a proc structure and the data hanging from it, including user pages. @@ -215,24 +242,6 @@ pub unsafe extern "C" fn reparent(p: *mut Process) { } } -/// Grow or shrink user memory by n bytes. -/// Return 0 on success, -1 on failure. -pub unsafe fn growproc(n: i32) -> i32 { - let p = Process::current().unwrap(); - let mut sz = p.sz; - - if n > 0 { - sz = uvmalloc(p.pagetable, sz, sz.wrapping_add(n as u64), PTE_W); - if sz == 0 { - return -1; - } - } else if n < 0 { - sz = uvmdealloc(p.pagetable, sz, sz.wrapping_add(n as u64)); - } - p.sz = sz; - 0 -} - /// Kill the process with the given pid. /// The victim won't exit until it tries to return /// to user space (see usertrap() in trap.c). diff --git a/kernel/rustkernel/src/syscall.rs b/kernel/rustkernel/src/syscall.rs index db37775..c770335 100644 --- a/kernel/rustkernel/src/syscall.rs +++ b/kernel/rustkernel/src/syscall.rs @@ -142,12 +142,13 @@ impl Syscall { Syscall::Sbrk => { let mut n = 0i32; argint(0, addr_of_mut!(n)); - let addr = Process::current().unwrap().sz; + let proc = Process::current().unwrap(); + let addr = proc.sz; - if process::growproc(n) < 0 { - -1i64 as u64 - } else { + if unsafe { proc.grow_memory(n).is_ok() } { addr + } else { + -1i64 as u64 } } Syscall::Sleep => {