finally finish rewriting proc.c
This commit is contained in:
parent
931884f6df
commit
e6c0bfc581
@ -2,7 +2,6 @@ R=rustkernel
|
|||||||
|
|
||||||
KERNEL_SOURCES = \
|
KERNEL_SOURCES = \
|
||||||
entry.c \
|
entry.c \
|
||||||
proc.c \
|
|
||||||
swtch.c \
|
swtch.c \
|
||||||
trampoline.c \
|
trampoline.c \
|
||||||
bio.c \
|
bio.c \
|
||||||
|
@ -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];
|
|
9
kernel/rustkernel/Cargo.lock
generated
9
kernel/rustkernel/Cargo.lock
generated
@ -2,6 +2,15 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arrayvec"
|
||||||
|
version = "0.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustkernel"
|
name = "rustkernel"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
]
|
||||||
|
@ -8,6 +8,7 @@ readme = "../../README.md"
|
|||||||
license = "LGPL-3.0-only"
|
license = "LGPL-3.0-only"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
arrayvec = { version = "0.7.4", default-features = false }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["staticlib"]
|
crate-type = ["staticlib"]
|
||||||
|
@ -33,9 +33,9 @@ use core::{
|
|||||||
ptr::{addr_of, addr_of_mut, null_mut},
|
ptr::{addr_of, addr_of_mut, null_mut},
|
||||||
sync::atomic::{AtomicI32, Ordering},
|
sync::atomic::{AtomicI32, Ordering},
|
||||||
};
|
};
|
||||||
|
use arrayvec::ArrayVec;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub static mut proc: [Process; crate::NPROC];
|
|
||||||
// trampoline.S
|
// trampoline.S
|
||||||
pub static mut trampoline: *mut c_char;
|
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.
|
/// Must be acquired before any p->lock.
|
||||||
pub static mut WAIT_LOCK: Spinlock = Spinlock::new();
|
pub static mut WAIT_LOCK: Spinlock = Spinlock::new();
|
||||||
pub static mut INITPROC: usize = 0;
|
pub static mut INITPROC: usize = 0;
|
||||||
|
pub static mut PROCESSES: ArrayVec<Process, { crate::NPROC }> = ArrayVec::new_const();
|
||||||
|
|
||||||
/// Initialize the proc table.
|
/// Initialize the proc table.
|
||||||
pub unsafe fn procinit() {
|
pub unsafe fn procinit() {
|
||||||
for (i, p) in proc.iter_mut().enumerate() {
|
let mut i = 0;
|
||||||
*p = Process::new();
|
let processes_iter = core::iter::repeat_with(|| {
|
||||||
|
let mut p = Process::new();
|
||||||
p.state = ProcessState::Unused;
|
p.state = ProcessState::Unused;
|
||||||
p.kernel_stack = kstack(i) as u64;
|
p.kernel_stack = kstack(i) as u64;
|
||||||
}
|
i += 1;
|
||||||
|
p
|
||||||
|
});
|
||||||
|
PROCESSES = processes_iter.take(crate::NPROC).collect();
|
||||||
}
|
}
|
||||||
/// Set up the first user process.
|
/// Set up the first user process.
|
||||||
pub unsafe fn userinit() {
|
pub unsafe fn userinit() {
|
||||||
@ -190,7 +195,7 @@ impl Process {
|
|||||||
/// If there are no free procs, or a memory allocation fails, return an error.
|
/// If there are no free procs, or a memory allocation fails, return an error.
|
||||||
pub unsafe fn alloc() -> Result<&'static mut Process, ProcessError> {
|
pub unsafe fn alloc() -> Result<&'static mut Process, ProcessError> {
|
||||||
let mut index: Option<usize> = None;
|
let mut index: Option<usize> = None;
|
||||||
for (i, p) in &mut proc.iter_mut().enumerate() {
|
for (i, p) in PROCESSES.iter_mut().enumerate() {
|
||||||
p.lock.lock_unguarded();
|
p.lock.lock_unguarded();
|
||||||
if p.state == ProcessState::Unused {
|
if p.state == ProcessState::Unused {
|
||||||
index = Some(i);
|
index = Some(i);
|
||||||
@ -203,7 +208,7 @@ impl Process {
|
|||||||
return Err(ProcessError::MaxProcesses);
|
return Err(ProcessError::MaxProcesses);
|
||||||
};
|
};
|
||||||
|
|
||||||
let p: &mut Process = &mut proc[index];
|
let p: &mut Process = &mut PROCESSES[index];
|
||||||
p.pid = Process::alloc_pid();
|
p.pid = Process::alloc_pid();
|
||||||
p.state = ProcessState::Used;
|
p.state = ProcessState::Used;
|
||||||
|
|
||||||
@ -390,7 +395,7 @@ impl Process {
|
|||||||
/// Pass p's abandoned children to init.
|
/// Pass p's abandoned children to init.
|
||||||
/// Caller must hold WAIT_LOCK.
|
/// Caller must hold WAIT_LOCK.
|
||||||
pub unsafe fn reparent(&self) {
|
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() {
|
if p.parent == addr_of!(*self).cast_mut() {
|
||||||
p.parent = INITPROC as *mut Process;
|
p.parent = INITPROC as *mut Process;
|
||||||
wakeup((INITPROC as *mut Process).cast());
|
wakeup((INITPROC as *mut Process).cast());
|
||||||
@ -447,7 +452,7 @@ impl Process {
|
|||||||
// Scan through the table looking for exited children.
|
// Scan through the table looking for exited children.
|
||||||
let mut has_children = false;
|
let mut has_children = false;
|
||||||
|
|
||||||
for p in &mut proc {
|
for p in PROCESSES.iter_mut() {
|
||||||
if p.parent == addr_of_mut!(*self) {
|
if p.parent == addr_of_mut!(*self) {
|
||||||
has_children = true;
|
has_children = true;
|
||||||
|
|
||||||
@ -496,7 +501,7 @@ impl Process {
|
|||||||
/// The victim won't exit until it tries to return
|
/// The victim won't exit until it tries to return
|
||||||
/// to user space (see usertrap() in trap.c).
|
/// to user space (see usertrap() in trap.c).
|
||||||
pub unsafe fn kill(pid: i32) -> bool {
|
pub unsafe fn kill(pid: i32) -> bool {
|
||||||
for p in &mut proc {
|
for p in PROCESSES.iter_mut() {
|
||||||
let _guard = p.lock.lock();
|
let _guard = p.lock.lock();
|
||||||
|
|
||||||
if p.pid == pid {
|
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]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn proc_pagetable(p: *mut Process) -> Pagetable {
|
pub unsafe extern "C" fn proc_pagetable(p: *mut Process) -> Pagetable {
|
||||||
(*p).alloc_pagetable().unwrap_or(null_mut())
|
(*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.
|
/// No lock to avoid wedging a stuck machine further.
|
||||||
pub unsafe fn procdump() {
|
pub unsafe fn procdump() {
|
||||||
uprintln!("\nprocdump:");
|
uprintln!("\nprocdump:");
|
||||||
for p in &proc {
|
for p in PROCESSES.iter() {
|
||||||
if p.state != ProcessState::Unused {
|
if p.state != ProcessState::Unused {
|
||||||
uprintln!(" {}: {:?}", p.pid, p.state);
|
uprintln!(" {}: {:?}", p.pid, p.state);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::{
|
use super::{
|
||||||
context::Context,
|
context::Context,
|
||||||
cpu::Cpu,
|
cpu::Cpu,
|
||||||
process::{proc, Process, ProcessState},
|
process::{PROCESSES, Process, ProcessState},
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
arch,
|
arch,
|
||||||
@ -41,7 +41,7 @@ pub unsafe fn scheduler() -> ! {
|
|||||||
// Avoid deadlock by ensuring that devices can interrupt.
|
// Avoid deadlock by ensuring that devices can interrupt.
|
||||||
arch::interrupt::enable_interrupts();
|
arch::interrupt::enable_interrupts();
|
||||||
|
|
||||||
for p in &mut proc {
|
for p in PROCESSES.iter_mut() {
|
||||||
let _guard = p.lock.lock();
|
let _guard = p.lock.lock();
|
||||||
if p.state == ProcessState::Runnable {
|
if p.state == ProcessState::Runnable {
|
||||||
// Switch to the chosen process. It's the process's job
|
// 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.
|
/// Must be called without any p.lock.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn wakeup(chan: *mut c_void) {
|
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() {
|
if !p.is_current() {
|
||||||
let _guard = p.lock.lock();
|
let _guard = p.lock.lock();
|
||||||
if p.state == ProcessState::Sleeping && p.chan == chan {
|
if p.state == ProcessState::Sleeping && p.chan == chan {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user