mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-14 15:56:47 +00:00
Change idle task to lowest priority
This commit is contained in:
parent
1186fb7ca9
commit
63364813a8
@ -37,6 +37,7 @@ use ostd::{
|
||||
arch::qemu::{exit_qemu, QemuExitCode},
|
||||
boot,
|
||||
cpu::PinCurrentCpu,
|
||||
task::Priority,
|
||||
};
|
||||
use process::Process;
|
||||
|
||||
@ -90,7 +91,7 @@ pub fn main() {
|
||||
ostd::boot::smp::register_ap_entry(ap_init);
|
||||
|
||||
// Spawn the first kernel thread on BSP.
|
||||
Thread::spawn_kernel_thread(ThreadOptions::new(init_thread));
|
||||
Thread::spawn_kernel_thread(ThreadOptions::new(init_thread).priority(Priority::lowest()));
|
||||
// Spawning functions in the bootstrap context will not return.
|
||||
unreachable!()
|
||||
}
|
||||
@ -122,7 +123,11 @@ fn ap_init() -> ! {
|
||||
let cpu_id = preempt_guard.current_cpu();
|
||||
drop(preempt_guard);
|
||||
|
||||
Thread::spawn_kernel_thread(ThreadOptions::new(ap_idle_thread).cpu_affinity(cpu_id.into()));
|
||||
Thread::spawn_kernel_thread(
|
||||
ThreadOptions::new(ap_idle_thread)
|
||||
.cpu_affinity(cpu_id.into())
|
||||
.priority(Priority::lowest()),
|
||||
);
|
||||
// Spawning functions in the bootstrap context will not return.
|
||||
unreachable!()
|
||||
}
|
||||
|
@ -53,7 +53,9 @@ impl<T: PreemptSchedInfo> PreemptScheduler<T> {
|
||||
let rq = self.rq[candidate].lock();
|
||||
// A wild guess measuring the load of a runqueue. We assume that
|
||||
// real-time tasks are 4-times as important as normal tasks.
|
||||
let load = rq.real_time_entities.len() * 4 + rq.normal_entities.len();
|
||||
let load = rq.real_time_entities.len() * 8
|
||||
+ rq.normal_entities.len() * 2
|
||||
+ rq.lowest_entities.len();
|
||||
if load < minimum_load {
|
||||
selected = candidate as u32;
|
||||
minimum_load = load;
|
||||
@ -85,6 +87,8 @@ impl<T: Sync + Send + PreemptSchedInfo> Scheduler<T> for PreemptScheduler<T> {
|
||||
let entity = PreemptSchedEntity::new(runnable);
|
||||
if entity.is_real_time() {
|
||||
rq.real_time_entities.push_back(entity);
|
||||
} else if entity.is_lowest() {
|
||||
rq.lowest_entities.push_back(entity);
|
||||
} else {
|
||||
rq.normal_entities.push_back(entity);
|
||||
}
|
||||
@ -116,6 +120,7 @@ struct PreemptRunQueue<T: PreemptSchedInfo> {
|
||||
current: Option<PreemptSchedEntity<T>>,
|
||||
real_time_entities: VecDeque<PreemptSchedEntity<T>>,
|
||||
normal_entities: VecDeque<PreemptSchedEntity<T>>,
|
||||
lowest_entities: VecDeque<PreemptSchedEntity<T>>,
|
||||
}
|
||||
|
||||
impl<T: PreemptSchedInfo> PreemptRunQueue<T> {
|
||||
@ -124,6 +129,7 @@ impl<T: PreemptSchedInfo> PreemptRunQueue<T> {
|
||||
current: None,
|
||||
real_time_entities: VecDeque::new(),
|
||||
normal_entities: VecDeque::new(),
|
||||
lowest_entities: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -149,12 +155,16 @@ impl<T: Sync + Send + PreemptSchedInfo> LocalRunQueue<T> for PreemptRunQueue<T>
|
||||
fn pick_next_current(&mut self) -> Option<&Arc<T>> {
|
||||
let next_entity = if !self.real_time_entities.is_empty() {
|
||||
self.real_time_entities.pop_front()
|
||||
} else {
|
||||
} else if !self.normal_entities.is_empty() {
|
||||
self.normal_entities.pop_front()
|
||||
} else {
|
||||
self.lowest_entities.pop_front()
|
||||
}?;
|
||||
if let Some(prev_entity) = self.current.replace(next_entity) {
|
||||
if prev_entity.is_real_time() {
|
||||
self.real_time_entities.push_back(prev_entity);
|
||||
} else if prev_entity.is_lowest() {
|
||||
self.lowest_entities.push_back(prev_entity);
|
||||
} else {
|
||||
self.normal_entities.push_back(prev_entity);
|
||||
}
|
||||
@ -190,6 +200,10 @@ impl<T: PreemptSchedInfo> PreemptSchedEntity<T> {
|
||||
self.runnable.is_real_time()
|
||||
}
|
||||
|
||||
fn is_lowest(&self) -> bool {
|
||||
self.runnable.is_lowest()
|
||||
}
|
||||
|
||||
fn tick(&mut self) -> bool {
|
||||
self.time_slice.elapse()
|
||||
}
|
||||
@ -233,6 +247,7 @@ impl PreemptSchedInfo for Task {
|
||||
type PRIORITY = Priority;
|
||||
|
||||
const REAL_TIME_TASK_PRIORITY: Self::PRIORITY = Priority::new(100);
|
||||
const LOWEST_TASK_PRIORITY: Self::PRIORITY = Priority::lowest();
|
||||
|
||||
fn priority(&self) -> Self::PRIORITY {
|
||||
self.schedule_info().priority
|
||||
@ -251,6 +266,7 @@ trait PreemptSchedInfo {
|
||||
type PRIORITY: Ord + PartialOrd + Eq + PartialEq;
|
||||
|
||||
const REAL_TIME_TASK_PRIORITY: Self::PRIORITY;
|
||||
const LOWEST_TASK_PRIORITY: Self::PRIORITY;
|
||||
|
||||
fn priority(&self) -> Self::PRIORITY;
|
||||
|
||||
@ -261,4 +277,8 @@ trait PreemptSchedInfo {
|
||||
fn is_real_time(&self) -> bool {
|
||||
self.priority() < Self::REAL_TIME_TASK_PRIORITY
|
||||
}
|
||||
|
||||
fn is_lowest(&self) -> bool {
|
||||
self.priority() == Self::LOWEST_TASK_PRIORITY
|
||||
}
|
||||
}
|
||||
|
@ -35,39 +35,45 @@ pub const REAL_TIME_TASK_PRIORITY: u16 = 100;
|
||||
pub struct Priority(u16);
|
||||
|
||||
impl Priority {
|
||||
const LOWEST: u16 = 139;
|
||||
const LOW: u16 = 110;
|
||||
const NORMAL: u16 = 100;
|
||||
const HIGH: u16 = 10;
|
||||
const HIGHEST: u16 = 0;
|
||||
|
||||
/// Creates a new `Priority` with the specified value.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the `val` is greater than 139.
|
||||
pub const fn new(val: u16) -> Self {
|
||||
assert!(val <= 139);
|
||||
assert!(val <= Self::LOWEST);
|
||||
Self(val)
|
||||
}
|
||||
|
||||
/// Returns a `Priority` representing the lowest priority (139).
|
||||
pub const fn lowest() -> Self {
|
||||
Self::new(139)
|
||||
Self::new(Self::LOWEST)
|
||||
}
|
||||
|
||||
/// Returns a `Priority` representing a low priority.
|
||||
pub const fn low() -> Self {
|
||||
Self::new(110)
|
||||
Self::new(Self::LOW)
|
||||
}
|
||||
|
||||
/// Returns a `Priority` representing a normal priority.
|
||||
pub const fn normal() -> Self {
|
||||
Self::new(100)
|
||||
Self::new(Self::NORMAL)
|
||||
}
|
||||
|
||||
/// Returns a `Priority` representing a high priority.
|
||||
pub const fn high() -> Self {
|
||||
Self::new(10)
|
||||
Self::new(Self::HIGH)
|
||||
}
|
||||
|
||||
/// Returns a `Priority` representing the highest priority (0).
|
||||
pub const fn highest() -> Self {
|
||||
Self::new(0)
|
||||
Self::new(Self::HIGHEST)
|
||||
}
|
||||
|
||||
/// Sets the value of the `Priority`.
|
||||
|
Loading…
x
Reference in New Issue
Block a user