extract scheduler functions into new module
This commit is contained in:
parent
71f9a49704
commit
87b00c924f
@ -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};
|
||||
|
@ -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;
|
||||
|
@ -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};
|
||||
|
@ -82,7 +82,7 @@ pub unsafe fn main() -> ! {
|
||||
arch::riscv::plic::plicinithart();
|
||||
}
|
||||
|
||||
proc::process::scheduler();
|
||||
proc::scheduler::scheduler();
|
||||
}
|
||||
|
||||
#[panic_handler]
|
||||
|
@ -1,4 +1,5 @@
|
||||
pub mod context;
|
||||
pub mod cpu;
|
||||
pub mod process;
|
||||
pub mod scheduler;
|
||||
pub mod trapframe;
|
||||
|
@ -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).
|
||||
|
77
kernel/rustkernel/src/proc/scheduler.rs
Normal file
77
kernel/rustkernel/src/proc/scheduler.rs
Normal 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();
|
||||
}
|
@ -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,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::proc::process::{sleep, wakeup};
|
||||
use crate::proc::scheduler::{sleep, wakeup};
|
||||
use core::{
|
||||
ffi::c_char,
|
||||
ptr::addr_of,
|
||||
|
@ -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::{
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user