mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-21 00:06:34 +00:00
Don't preempt without good reason
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
19b13d88e2
commit
5233827160
@ -93,8 +93,6 @@ pub fn main() {
|
|||||||
ThreadOptions::new(init_thread)
|
ThreadOptions::new(init_thread)
|
||||||
.priority(Priority::new(PriorityRange::new(PriorityRange::MAX))),
|
.priority(Priority::new(PriorityRange::new(PriorityRange::MAX))),
|
||||||
);
|
);
|
||||||
// Spawning functions in the bootstrap context will not return.
|
|
||||||
unreachable!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
@ -110,7 +108,7 @@ pub fn init() {
|
|||||||
process::init();
|
process::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ap_init() -> ! {
|
fn ap_init() {
|
||||||
fn ap_idle_thread() {
|
fn ap_idle_thread() {
|
||||||
let preempt_guard = ostd::task::disable_preempt();
|
let preempt_guard = ostd::task::disable_preempt();
|
||||||
let cpu_id = preempt_guard.current_cpu();
|
let cpu_id = preempt_guard.current_cpu();
|
||||||
@ -129,8 +127,6 @@ fn ap_init() -> ! {
|
|||||||
.cpu_affinity(cpu_id.into())
|
.cpu_affinity(cpu_id.into())
|
||||||
.priority(Priority::new(PriorityRange::new(PriorityRange::MAX))),
|
.priority(Priority::new(PriorityRange::new(PriorityRange::MAX))),
|
||||||
);
|
);
|
||||||
// Spawning functions in the bootstrap context will not return.
|
|
||||||
unreachable!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_thread() {
|
fn init_thread() {
|
||||||
|
@ -104,6 +104,9 @@ impl<T: Sync + Send + PreemptSchedInfo + FromTask<U>, U: Sync + Send + CommonSch
|
|||||||
if still_in_rq && let Err(_) = entity.task.cpu().set_if_is_none(target_cpu) {
|
if still_in_rq && let Err(_) = entity.task.cpu().set_if_is_none(target_cpu) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let new_priority = entity.thread.priority();
|
||||||
|
|
||||||
if entity.thread.is_real_time() {
|
if entity.thread.is_real_time() {
|
||||||
rq.real_time_entities.push_back(entity);
|
rq.real_time_entities.push_back(entity);
|
||||||
} else if entity.thread.is_lowest() {
|
} else if entity.thread.is_lowest() {
|
||||||
@ -112,7 +115,17 @@ impl<T: Sync + Send + PreemptSchedInfo + FromTask<U>, U: Sync + Send + CommonSch
|
|||||||
rq.normal_entities.push_back(entity);
|
rq.normal_entities.push_back(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Preempt the current task, but only if the newly queued task has a strictly higher
|
||||||
|
// priority (i.e., a lower value returned by the `priority` method) than the current task.
|
||||||
|
if rq
|
||||||
|
.current
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|current| new_priority < current.thread.priority())
|
||||||
|
{
|
||||||
Some(target_cpu)
|
Some(target_cpu)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_rq_with(&self, f: &mut dyn FnMut(&dyn LocalRunQueue<U>)) {
|
fn local_rq_with(&self, f: &mut dyn FnMut(&dyn LocalRunQueue<U>)) {
|
||||||
|
@ -49,9 +49,7 @@ fn main() {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
let _ = TaskOptions::new(test_task).data(()).spawn();
|
TaskOptions::new(test_task).data(()).spawn().unwrap();
|
||||||
|
|
||||||
unreachable!("The spawn method will NOT return in the boot context")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[ostd::ktest::panic_handler]
|
#[ostd::ktest::panic_handler]
|
||||||
|
@ -30,8 +30,10 @@ pub fn main(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||||||
#[cfg(not(ktest))]
|
#[cfg(not(ktest))]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "Rust" fn __ostd_main() -> ! {
|
extern "Rust" fn __ostd_main() -> ! {
|
||||||
#main_fn_name();
|
let _: () = #main_fn_name();
|
||||||
ostd::prelude::abort();
|
|
||||||
|
ostd::task::Task::yield_now();
|
||||||
|
unreachable!("`yield_now` in the boot context should not return");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
@ -52,8 +54,10 @@ pub fn test_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||||||
quote!(
|
quote!(
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "Rust" fn __ostd_main() -> ! {
|
extern "Rust" fn __ostd_main() -> ! {
|
||||||
#main_fn_name();
|
let _: () = #main_fn_name();
|
||||||
ostd::prelude::abort();
|
|
||||||
|
ostd::task::Task::yield_now();
|
||||||
|
unreachable!("`yield_now` in the boot context should not return");
|
||||||
}
|
}
|
||||||
|
|
||||||
#main_fn
|
#main_fn
|
||||||
|
@ -15,6 +15,7 @@ use crate::{
|
|||||||
page::{self, meta::KernelMeta, ContPages},
|
page::{self, meta::KernelMeta, ContPages},
|
||||||
PAGE_SIZE,
|
PAGE_SIZE,
|
||||||
},
|
},
|
||||||
|
task::Task,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) static AP_BOOT_INFO: Once<ApBootInfo> = Once::new();
|
pub(crate) static AP_BOOT_INFO: Once<ApBootInfo> = Once::new();
|
||||||
@ -37,7 +38,7 @@ struct PerApInfo {
|
|||||||
boot_stack_pages: ContPages<KernelMeta>,
|
boot_stack_pages: ContPages<KernelMeta>,
|
||||||
}
|
}
|
||||||
|
|
||||||
static AP_LATE_ENTRY: Once<fn() -> !> = Once::new();
|
static AP_LATE_ENTRY: Once<fn()> = Once::new();
|
||||||
|
|
||||||
/// Boot all application processors.
|
/// Boot all application processors.
|
||||||
///
|
///
|
||||||
@ -104,7 +105,7 @@ pub fn boot_all_aps() {
|
|||||||
///
|
///
|
||||||
/// Once the entry function is registered, all the application processors
|
/// Once the entry function is registered, all the application processors
|
||||||
/// will jump to the entry function immediately.
|
/// will jump to the entry function immediately.
|
||||||
pub fn register_ap_entry(entry: fn() -> !) {
|
pub fn register_ap_entry(entry: fn()) {
|
||||||
AP_LATE_ENTRY.call_once(|| entry);
|
AP_LATE_ENTRY.call_once(|| entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,6 +151,9 @@ fn ap_early_entry(local_apic_id: u32) -> ! {
|
|||||||
|
|
||||||
let ap_late_entry = AP_LATE_ENTRY.wait();
|
let ap_late_entry = AP_LATE_ENTRY.wait();
|
||||||
ap_late_entry();
|
ap_late_entry();
|
||||||
|
|
||||||
|
Task::yield_now();
|
||||||
|
unreachable!("`yield_now` in the boot context should not return");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wait_for_all_aps_started() {
|
fn wait_for_all_aps_started() {
|
||||||
|
@ -58,7 +58,8 @@ impl<T: CommonSchedInfo + Send + Sync> Scheduler<T> for FifoScheduler<T> {
|
|||||||
}
|
}
|
||||||
rq.queue.push_back(runnable);
|
rq.queue.push_back(runnable);
|
||||||
|
|
||||||
Some(target_cpu)
|
// All tasks are important. Do not preempt the current task without good reason.
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_rq_with(&self, f: &mut dyn FnMut(&dyn LocalRunQueue<T>)) {
|
fn local_rq_with(&self, f: &mut dyn FnMut(&dyn LocalRunQueue<T>)) {
|
||||||
|
Reference in New Issue
Block a user