schedule tasks based on last run time

This commit is contained in:
Ashwin Naren
2025-11-26 23:37:23 -08:00
committed by Matthew Leach
parent e9f3f8764d
commit eff3dad5c7
3 changed files with 23 additions and 1 deletions

View File

@@ -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),
}
};

View File

@@ -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),
}
}

View File

@@ -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()
}