mirror of
https://github.com/hexagonal-sun/moss-kernel.git
synced 2026-06-11 18:36:03 -04:00
schedule tasks based on last run time
This commit is contained in:
committed by
Matthew Leach
parent
e9f3f8764d
commit
eff3dad5c7
@@ -125,6 +125,7 @@ pub async fn sys_clone(
|
||||
sig_mask: SpinLock::new(new_sigmask),
|
||||
pending_signals: SpinLock::new(SigSet::empty()),
|
||||
state: Arc::new(SpinLock::new(TaskState::Runnable)),
|
||||
last_run: SpinLock::new(None),
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::drivers::timer::Instant;
|
||||
use crate::{
|
||||
arch::{Arch, ArchImpl},
|
||||
fs::DummyInode,
|
||||
@@ -125,6 +126,7 @@ pub struct Task {
|
||||
pub sig_mask: SpinLock<SigSet>,
|
||||
pub pending_signals: SpinLock<SigSet>,
|
||||
pub priority: i8,
|
||||
pub last_run: SpinLock<Option<Instant>>,
|
||||
pub state: Arc<SpinLock<TaskState>>,
|
||||
}
|
||||
|
||||
@@ -152,6 +154,7 @@ impl Task {
|
||||
sig_mask: SpinLock::new(SigSet::empty()),
|
||||
pending_signals: SpinLock::new(SigSet::empty()),
|
||||
fd_table: Arc::new(SpinLock::new(FileDescriptorTable::new())),
|
||||
last_run: SpinLock::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,6 +175,7 @@ impl Task {
|
||||
ctx: SpinLock::new(Context::from_user_ctx(
|
||||
<ArchImpl as Arch>::new_user_context(VA::null(), VA::null()),
|
||||
)),
|
||||
last_run: SpinLock::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::drivers::timer::now;
|
||||
use crate::{
|
||||
arch::{Arch, ArchImpl},
|
||||
per_cpu,
|
||||
@@ -5,6 +6,7 @@ use crate::{
|
||||
sync::OnceLock,
|
||||
};
|
||||
use alloc::{boxed::Box, collections::btree_map::BTreeMap, sync::Arc};
|
||||
use core::cmp::Ordering;
|
||||
use libkernel::{UserAddressSpace, error::Result};
|
||||
|
||||
pub mod uspc_ret;
|
||||
@@ -42,6 +44,7 @@ fn schedule() {
|
||||
}
|
||||
|
||||
let previous_task = current_task();
|
||||
*previous_task.last_run.lock_save_irq() = now();
|
||||
let mut sched_state = SCHED_STATE.borrow_mut();
|
||||
let next_task = sched_state.find_next_runnable_task();
|
||||
|
||||
@@ -125,7 +128,21 @@ impl SchedState {
|
||||
// A process is a candidate if it's runnable and NOT the idle task
|
||||
state == TaskState::Runnable && !candidate_proc.is_idle_task()
|
||||
})
|
||||
.max_by_key(|proc| proc.priority())
|
||||
.max_by(|proc1, proc2| {
|
||||
proc1.priority().cmp(&proc2.priority()).then_with(|| {
|
||||
// If priorities are the same, use last run time to
|
||||
// decide.
|
||||
let last_run1 = proc1.last_run.lock_save_irq();
|
||||
let last_run2 = proc2.last_run.lock_save_irq();
|
||||
|
||||
match (*last_run1, *last_run2) {
|
||||
(Some(t1), Some(t2)) => t1.cmp(&t2),
|
||||
(Some(_), None) => Ordering::Greater,
|
||||
(None, Some(_)) => Ordering::Less,
|
||||
(None, None) => Ordering::Equal,
|
||||
}
|
||||
})
|
||||
})
|
||||
.unwrap_or(idle_task)
|
||||
.clone()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user