From e6c0bfc581d632aa393d687f995ae168f5dcb938 Mon Sep 17 00:00:00 2001 From: Garen Tyler Date: Sun, 12 Nov 2023 15:36:46 -0700 Subject: [PATCH] finally finish rewriting proc.c --- kernel/Makefile | 1 - kernel/proc.c | 9 ------- kernel/rustkernel/Cargo.lock | 9 +++++++ kernel/rustkernel/Cargo.toml | 1 + kernel/rustkernel/src/proc/process.rs | 34 +++++++++++-------------- kernel/rustkernel/src/proc/scheduler.rs | 6 ++--- 6 files changed, 28 insertions(+), 32 deletions(-) delete mode 100644 kernel/proc.c diff --git a/kernel/Makefile b/kernel/Makefile index 2b6bfa1..e9ccaa4 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -2,7 +2,6 @@ R=rustkernel KERNEL_SOURCES = \ entry.c \ - proc.c \ swtch.c \ trampoline.c \ bio.c \ diff --git a/kernel/proc.c b/kernel/proc.c deleted file mode 100644 index 4bd97e4..0000000 --- a/kernel/proc.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "types.h" -#include "param.h" -#include "memlayout.h" -#include "riscv.h" -#include "spinlock.h" -#include "proc.h" -#include "defs.h" - -struct proc proc[NPROC]; diff --git a/kernel/rustkernel/Cargo.lock b/kernel/rustkernel/Cargo.lock index 516fd1e..86e1837 100644 --- a/kernel/rustkernel/Cargo.lock +++ b/kernel/rustkernel/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "rustkernel" version = "0.1.0" +dependencies = [ + "arrayvec", +] diff --git a/kernel/rustkernel/Cargo.toml b/kernel/rustkernel/Cargo.toml index e410fba..7ba692f 100644 --- a/kernel/rustkernel/Cargo.toml +++ b/kernel/rustkernel/Cargo.toml @@ -8,6 +8,7 @@ readme = "../../README.md" license = "LGPL-3.0-only" [dependencies] +arrayvec = { version = "0.7.4", default-features = false } [lib] crate-type = ["staticlib"] diff --git a/kernel/rustkernel/src/proc/process.rs b/kernel/rustkernel/src/proc/process.rs index 8a05868..bec0e9f 100644 --- a/kernel/rustkernel/src/proc/process.rs +++ b/kernel/rustkernel/src/proc/process.rs @@ -33,9 +33,9 @@ use core::{ ptr::{addr_of, addr_of_mut, null_mut}, sync::atomic::{AtomicI32, Ordering}, }; +use arrayvec::ArrayVec; extern "C" { - pub static mut proc: [Process; crate::NPROC]; // trampoline.S pub static mut trampoline: *mut c_char; } @@ -47,14 +47,19 @@ pub static NEXT_PID: AtomicI32 = AtomicI32::new(1); /// Must be acquired before any p->lock. pub static mut WAIT_LOCK: Spinlock = Spinlock::new(); pub static mut INITPROC: usize = 0; +pub static mut PROCESSES: ArrayVec = ArrayVec::new_const(); /// Initialize the proc table. pub unsafe fn procinit() { - for (i, p) in proc.iter_mut().enumerate() { - *p = Process::new(); + let mut i = 0; + let processes_iter = core::iter::repeat_with(|| { + let mut p = Process::new(); p.state = ProcessState::Unused; p.kernel_stack = kstack(i) as u64; - } + i += 1; + p + }); + PROCESSES = processes_iter.take(crate::NPROC).collect(); } /// Set up the first user process. pub unsafe fn userinit() { @@ -190,7 +195,7 @@ impl Process { /// If there are no free procs, or a memory allocation fails, return an error. pub unsafe fn alloc() -> Result<&'static mut Process, ProcessError> { let mut index: Option = None; - for (i, p) in &mut proc.iter_mut().enumerate() { + for (i, p) in PROCESSES.iter_mut().enumerate() { p.lock.lock_unguarded(); if p.state == ProcessState::Unused { index = Some(i); @@ -203,7 +208,7 @@ impl Process { return Err(ProcessError::MaxProcesses); }; - let p: &mut Process = &mut proc[index]; + let p: &mut Process = &mut PROCESSES[index]; p.pid = Process::alloc_pid(); p.state = ProcessState::Used; @@ -390,7 +395,7 @@ impl Process { /// Pass p's abandoned children to init. /// Caller must hold WAIT_LOCK. pub unsafe fn reparent(&self) { - for p in proc.iter_mut() { + for p in PROCESSES.iter_mut() { if p.parent == addr_of!(*self).cast_mut() { p.parent = INITPROC as *mut Process; wakeup((INITPROC as *mut Process).cast()); @@ -447,7 +452,7 @@ impl Process { // Scan through the table looking for exited children. let mut has_children = false; - for p in &mut proc { + for p in PROCESSES.iter_mut() { if p.parent == addr_of_mut!(*self) { has_children = true; @@ -496,7 +501,7 @@ impl Process { /// The victim won't exit until it tries to return /// to user space (see usertrap() in trap.c). pub unsafe fn kill(pid: i32) -> bool { - for p in &mut proc { + for p in PROCESSES.iter_mut() { let _guard = p.lock.lock(); if p.pid == pid { @@ -537,15 +542,6 @@ pub extern "C" fn myproc() -> *mut Process { } } -#[no_mangle] -pub unsafe extern "C" fn allocproc() -> *mut Process { - if let Ok(process) = Process::alloc() { - process as *mut Process - } else { - null_mut() - } -} - #[no_mangle] pub unsafe extern "C" fn proc_pagetable(p: *mut Process) -> Pagetable { (*p).alloc_pagetable().unwrap_or(null_mut()) @@ -561,7 +557,7 @@ pub unsafe extern "C" fn proc_freepagetable(pagetable: Pagetable, size: u64) { /// No lock to avoid wedging a stuck machine further. pub unsafe fn procdump() { uprintln!("\nprocdump:"); - for p in &proc { + for p in PROCESSES.iter() { if p.state != ProcessState::Unused { uprintln!(" {}: {:?}", p.pid, p.state); } diff --git a/kernel/rustkernel/src/proc/scheduler.rs b/kernel/rustkernel/src/proc/scheduler.rs index 25b6288..e2384c2 100644 --- a/kernel/rustkernel/src/proc/scheduler.rs +++ b/kernel/rustkernel/src/proc/scheduler.rs @@ -1,7 +1,7 @@ use super::{ context::Context, cpu::Cpu, - process::{proc, Process, ProcessState}, + process::{PROCESSES, Process, ProcessState}, }; use crate::{ arch, @@ -41,7 +41,7 @@ pub unsafe fn scheduler() -> ! { // Avoid deadlock by ensuring that devices can interrupt. arch::interrupt::enable_interrupts(); - for p in &mut proc { + for p in PROCESSES.iter_mut() { let _guard = p.lock.lock(); if p.state == ProcessState::Runnable { // Switch to the chosen process. It's the process's job @@ -114,7 +114,7 @@ pub unsafe fn sleep(chan: *mut c_void) { /// Must be called without any p.lock. #[no_mangle] pub unsafe extern "C" fn wakeup(chan: *mut c_void) { - for p in &mut proc { + for p in PROCESSES.iter_mut() { if !p.is_current() { let _guard = p.lock.lock(); if p.state == ProcessState::Sleeping && p.chan == chan {