mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-10 13:56:48 +00:00
Halt the idle CPUs
This commit is contained in:
parent
265bc25dd7
commit
30ec0be210
@ -39,10 +39,7 @@ use ostd::{
|
||||
use process::Process;
|
||||
use sched::SchedPolicy;
|
||||
|
||||
use crate::{
|
||||
prelude::*,
|
||||
thread::{kernel_thread::ThreadOptions, Thread},
|
||||
};
|
||||
use crate::{prelude::*, thread::kernel_thread::ThreadOptions};
|
||||
|
||||
extern crate alloc;
|
||||
extern crate lru;
|
||||
@ -112,8 +109,10 @@ fn ap_init() {
|
||||
let cpu_id = preempt_guard.current_cpu();
|
||||
drop(preempt_guard);
|
||||
log::info!("Kernel idle thread for CPU #{} started.", cpu_id.as_usize());
|
||||
|
||||
loop {
|
||||
Thread::yield_now();
|
||||
crate::thread::Thread::yield_now();
|
||||
ostd::cpu::sleep_for_interrupt();
|
||||
}
|
||||
}
|
||||
let preempt_guard = ostd::task::disable_preempt();
|
||||
@ -154,9 +153,8 @@ fn init_thread() {
|
||||
.expect("Run init process failed.");
|
||||
// Wait till initproc become zombie.
|
||||
while !initproc.status().is_zombie() {
|
||||
// We don't have preemptive scheduler now.
|
||||
// The long running init thread should yield its own execution to allow other tasks to go on.
|
||||
Thread::yield_now();
|
||||
crate::thread::Thread::yield_now();
|
||||
ostd::cpu::sleep_for_interrupt();
|
||||
}
|
||||
|
||||
// TODO: exit via qemu isa debug device should not be the only way.
|
||||
|
@ -213,9 +213,18 @@ impl Scheduler for ClassScheduler {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Preempt if the new task has a higher priority.
|
||||
let should_preempt = rq
|
||||
.current
|
||||
.as_ref()
|
||||
.is_none_or(|((_, rq_current_thread), _)| {
|
||||
thread.sched_attr().policy() < rq_current_thread.sched_attr().policy()
|
||||
});
|
||||
|
||||
thread.sched_attr().set_last_cpu(cpu);
|
||||
rq.enqueue_entity((task, thread), Some(flags));
|
||||
Some(cpu)
|
||||
|
||||
should_preempt.then_some(cpu)
|
||||
}
|
||||
|
||||
fn local_mut_rq_with(&self, f: &mut dyn FnMut(&mut dyn LocalRunQueue)) {
|
||||
|
@ -4,3 +4,17 @@
|
||||
|
||||
pub mod context;
|
||||
pub mod local;
|
||||
|
||||
/// Halts the CPU.
|
||||
///
|
||||
/// This function halts the CPU until the next interrupt is received. By
|
||||
/// halting, the CPU might consume less power. Internally it is implemented
|
||||
/// using the `wfi` instruction.
|
||||
///
|
||||
/// Since the function sleeps the CPU, it should not be used within an atomic
|
||||
/// mode ([`crate::task::atomic_mode`]).
|
||||
#[track_caller]
|
||||
pub fn sleep_for_interrupt() {
|
||||
crate::task::atomic_mode::might_sleep();
|
||||
riscv::asm::wfi();
|
||||
}
|
||||
|
@ -4,3 +4,16 @@
|
||||
|
||||
pub mod context;
|
||||
pub mod local;
|
||||
|
||||
/// Halts the CPU.
|
||||
///
|
||||
/// This function halts the CPU until the next interrupt is received. By
|
||||
/// halting, the CPU will enter the C-0 state and consume less power.
|
||||
///
|
||||
/// Since the function sleeps the CPU, it should not be used within an atomic
|
||||
/// mode ([`crate::task::atomic_mode`]).
|
||||
#[track_caller]
|
||||
pub fn sleep_for_interrupt() {
|
||||
crate::task::atomic_mode::might_sleep();
|
||||
x86_64::instructions::hlt();
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
//! Tasks are the unit of code execution.
|
||||
|
||||
pub(crate) mod atomic_mode;
|
||||
pub mod atomic_mode;
|
||||
mod kernel_stack;
|
||||
mod preempt;
|
||||
mod processor;
|
||||
|
@ -12,7 +12,7 @@ use spin::Once;
|
||||
|
||||
use super::{preempt::cpu_local, processor, Task};
|
||||
use crate::{
|
||||
cpu::{CpuId, PinCurrentCpu},
|
||||
cpu::{CpuId, CpuSet, PinCurrentCpu},
|
||||
prelude::*,
|
||||
task::disable_preempt,
|
||||
timer,
|
||||
@ -195,7 +195,9 @@ fn set_need_preempt(cpu_id: CpuId) {
|
||||
if preempt_guard.current_cpu() == cpu_id {
|
||||
cpu_local::set_need_preempt();
|
||||
} else {
|
||||
// TODO: Send IPIs to set remote CPU's `need_preempt`
|
||||
crate::smp::inter_processor_call(&CpuSet::from(cpu_id), || {
|
||||
cpu_local::set_need_preempt();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user