extract scheduler functions into new module

This commit is contained in:
Garen Tyler 2023-11-03 19:14:38 -06:00
parent 71f9a49704
commit 87b00c924f
Signed by: garentyler
GPG Key ID: D7A048C454CB7054
11 changed files with 99 additions and 74 deletions

View File

@ -13,7 +13,10 @@ pub mod uart;
use crate::{
fs::file::{devsw, CONSOLE},
proc::process::{procdump, wakeup, Process},
proc::{
process::{procdump, Process},
scheduler::wakeup,
},
sync::mutex::Mutex,
};
use core::{ffi::c_void, ptr::addr_of_mut};

View File

@ -2,7 +2,7 @@
#![allow(non_upper_case_globals)]
use crate::{
console::consoleintr, proc::process::wakeup, queue::Queue, sync::mutex::Mutex,
console::consoleintr, proc::scheduler::wakeup, queue::Queue, sync::mutex::Mutex,
trap::InterruptBlocker,
};
use core::ptr::addr_of;

View File

@ -4,7 +4,7 @@ use crate::{
kalloc::{kalloc, kfree},
virtual_memory::{copyin, copyout},
},
proc::process::{wakeup, Process},
proc::{process::Process, scheduler::wakeup},
sync::spinlock::Spinlock,
};
use core::ptr::{addr_of, addr_of_mut};

View File

@ -82,7 +82,7 @@ pub unsafe fn main() -> ! {
arch::riscv::plic::plicinithart();
}
proc::process::scheduler();
proc::scheduler::scheduler();
}
#[panic_handler]

View File

@ -1,4 +1,5 @@
pub mod context;
pub mod cpu;
pub mod process;
pub mod scheduler;
pub mod trapframe;

View File

@ -1,11 +1,11 @@
#![allow(clippy::comparison_chain)]
use super::{context::Context, cpu::Cpu, trapframe::Trapframe};
use super::{context::Context, cpu::Cpu, scheduler::wakeup, trapframe::Trapframe};
use crate::{
arch::riscv::{intr_get, Pagetable, PTE_W},
arch::riscv::{Pagetable, PTE_W},
fs::file::{File, Inode},
mem::kalloc::kfree,
sync::spinlock::{Spinlock, SpinlockGuard},
sync::spinlock::Spinlock,
};
use core::{
ffi::{c_char, c_void},
@ -36,14 +36,9 @@ extern "C" {
pub fn proc_mapstacks(kpgtbl: Pagetable);
pub fn proc_pagetable(p: *mut Process) -> Pagetable;
pub fn proc_freepagetable(pagetable: Pagetable, sz: u64);
pub fn wakeup(chan: *const c_void);
pub fn allocproc() -> *mut Process;
// pub fn freeproc(p: *mut Process);
pub fn uvmalloc(pagetable: Pagetable, oldsz: u64, newsz: u64, xperm: i32) -> u64;
pub fn uvmdealloc(pagetable: Pagetable, oldsz: u64, newsz: u64) -> u64;
// pub fn sched();
pub fn scheduler() -> !;
pub fn swtch(a: *mut Context, b: *mut Context);
}
pub static NEXT_PID: AtomicI32 = AtomicI32::new(1);
@ -238,64 +233,6 @@ pub unsafe fn growproc(n: i32) -> i32 {
0
}
/// Give up the CPU for one scheduling round.
pub unsafe fn r#yield() {
let p = Process::current().unwrap();
let _guard = p.lock.lock();
p.state = ProcessState::Runnable;
sched();
}
/// Switch to scheduler. Must hold only p->lock
/// and have changed proc->state. Saves and restores
/// previous_interrupts_enabled because previous_interrupts_enabled is a property of this
/// kernel thread, not this CPU. It should
/// be proc->previous_interrupts_enabled and proc->interrupt_disable_layers, but that would
/// break in the few places where a lock is held but
/// there's no process.
#[no_mangle]
pub unsafe extern "C" fn sched() {
let p = Process::current().unwrap();
let cpu = Cpu::current();
if cpu.interrupt_disable_layers != 1 {
panic!("sched locks");
} else if p.state == ProcessState::Running {
panic!("sched running");
} else if intr_get() > 0 {
panic!("sched interruptible");
}
let previous_interrupts_enabled = cpu.previous_interrupts_enabled;
swtch(addr_of_mut!(p.context), addr_of_mut!(cpu.context));
cpu.previous_interrupts_enabled = previous_interrupts_enabled;
}
/// The lock should already be locked.
/// Unsafely create a new guard for it so that we can call SpinlockGuard.sleep().
#[no_mangle]
pub unsafe extern "C" fn sleep_lock(chan: *mut c_void, lock: *mut Spinlock) {
let lock: &Spinlock = &*lock;
let guard = SpinlockGuard { lock };
guard.sleep(chan);
core::mem::forget(guard);
}
/// Sleep until `wakeup(chan)` is called somewhere else.
pub unsafe fn sleep(chan: *mut c_void) {
let p = Process::current().unwrap();
let _guard = p.lock.lock();
// Go to sleep.
p.chan = chan;
p.state = ProcessState::Sleeping;
sched();
// Tidy up.
p.chan = null_mut();
}
/// 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).

View File

@ -0,0 +1,77 @@
use super::{
context::Context,
cpu::Cpu,
process::{Process, ProcessState},
};
use crate::{
arch::riscv::intr_get,
sync::spinlock::{Spinlock, SpinlockGuard},
};
use core::{
ffi::c_void,
ptr::{addr_of_mut, null_mut},
};
extern "C" {
pub fn wakeup(chan: *const c_void);
pub fn scheduler() -> !;
pub fn swtch(a: *mut Context, b: *mut Context);
}
/// Give up the CPU for one scheduling round.
pub unsafe fn r#yield() {
let p = Process::current().unwrap();
let _guard = p.lock.lock();
p.state = ProcessState::Runnable;
sched();
}
/// Switch to scheduler. Must hold only p->lock
/// and have changed proc->state. Saves and restores
/// previous_interrupts_enabled because previous_interrupts_enabled is a property of this
/// kernel thread, not this CPU. It should
/// be proc->previous_interrupts_enabled and proc->interrupt_disable_layers, but that would
/// break in the few places where a lock is held but
/// there's no process.
#[no_mangle]
pub unsafe extern "C" fn sched() {
let p = Process::current().unwrap();
let cpu = Cpu::current();
if cpu.interrupt_disable_layers != 1 {
panic!("sched locks");
} else if p.state == ProcessState::Running {
panic!("sched running");
} else if intr_get() > 0 {
panic!("sched interruptible");
}
let previous_interrupts_enabled = cpu.previous_interrupts_enabled;
swtch(addr_of_mut!(p.context), addr_of_mut!(cpu.context));
cpu.previous_interrupts_enabled = previous_interrupts_enabled;
}
/// The lock should already be locked.
/// Unsafely create a new guard for it so that we can call SpinlockGuard.sleep().
#[no_mangle]
pub unsafe extern "C" fn sleep_lock(chan: *mut c_void, lock: *mut Spinlock) {
let lock: &Spinlock = &*lock;
let guard = SpinlockGuard { lock };
guard.sleep(chan);
core::mem::forget(guard);
}
/// Sleep until `wakeup(chan)` is called somewhere else.
pub unsafe fn sleep(chan: *mut c_void) {
let p = Process::current().unwrap();
let _guard = p.lock.lock();
// Go to sleep.
p.chan = chan;
p.state = ProcessState::Sleeping;
sched();
// Tidy up.
p.chan = null_mut();
}

View File

@ -1,5 +1,8 @@
use super::LockStrategy;
use crate::proc::process::{sched, sleep, wakeup, Process, ProcessState};
use crate::proc::{
process::{Process, ProcessState},
scheduler::{sched, sleep, wakeup},
};
use core::{
cell::UnsafeCell,
ops::Drop,

View File

@ -1,4 +1,4 @@
use crate::proc::process::{sleep, wakeup};
use crate::proc::scheduler::{sleep, wakeup};
use core::{
ffi::c_char,
ptr::addr_of,

View File

@ -1,5 +1,8 @@
use crate::{
proc::process::{sched, Process, ProcessState},
proc::{
process::{Process, ProcessState},
scheduler::sched,
},
trap::{pop_intr_off, push_intr_off},
};
use core::{

View File

@ -3,7 +3,8 @@ use crate::{
println,
proc::{
cpu::Cpu,
process::{exit, r#yield, wakeup, Process, ProcessState},
process::{exit, Process, ProcessState},
scheduler::{r#yield, wakeup},
},
sync::mutex::Mutex,
syscall::syscall,