Skip to content

Commit

Permalink
Implement priority inheritance
Browse files Browse the repository at this point in the history
Signed-off-by: Klimenty Tsoutsman <klim@tsoutsman.com>
  • Loading branch information
tsoutsman committed Sep 8, 2023
1 parent 8917875 commit 618b5ce
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 75 deletions.
4 changes: 2 additions & 2 deletions kernel/scheduler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

use interrupts::{self, CPU_LOCAL_TIMER_IRQ, interrupt_handler, eoi, EoiBehaviour};

/// A re-export of [`task::schedule()`] for convenience and legacy compatibility.
pub use task::scheduler::{priority, schedule, set_priority};
/// Re-exports for convenience and legacy compatibility.
pub use task::scheduler::{inherit_priority, priority, schedule, set_priority};


/// Initializes the scheduler on this system using the policy set at compiler time.
Expand Down
7 changes: 0 additions & 7 deletions kernel/scheduler_epoch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,6 @@ impl task::scheduler::PriorityScheduler for Scheduler {
}
None
}

fn inherit_priority(
&mut self,
_task: &TaskRef,
) -> task::scheduler::PriorityInheritanceGuard<'_> {
todo!()
}
}

#[derive(Debug, Clone)]
Expand Down
7 changes: 0 additions & 7 deletions kernel/scheduler_priority/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,6 @@ impl task::scheduler::PriorityScheduler for Scheduler {
}
None
}

fn inherit_priority(
&mut self,
task: &TaskRef,
) -> task::scheduler::PriorityInheritanceGuard<'_> {
todo!()
}
}

#[derive(Clone, Debug, Eq)]
Expand Down
1 change: 1 addition & 0 deletions kernel/task/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#![no_std]
#![feature(negative_impls)]
#![feature(thread_local)]
#![feature(let_chains)]

extern crate alloc;

Expand Down
99 changes: 40 additions & 59 deletions kernel/task/src/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,21 +187,6 @@ pub trait PriorityScheduler {

/// Gets the priority of the given task.
fn priority(&mut self, task: &TaskRef) -> Option<u8>;

fn inherit_priority(&mut self, task: &TaskRef) -> PriorityInheritanceGuard<'_>;
}

/// Lowers the task's priority to its previous value when dropped.
pub struct PriorityInheritanceGuard<'a> {
inner: Option<(&'a TaskRef, u8)>,
}

impl<'a> Drop for PriorityInheritanceGuard<'a> {
fn drop(&mut self) {
if let Some((task, priority)) = self.inner {
set_priority(task, priority);
}
}
}

/// Returns the priority of the given task.
Expand Down Expand Up @@ -246,47 +231,43 @@ pub fn busyness(cpu_id: CpuId) -> Option<usize> {
None
}

// /// Modifies the given task's priority to be the maximum of its priority and
// the /// current task's priority.
// ///
// /// Returns a guard which reverts the change when dropped.
// pub fn inherit_priority(task: &TaskRef) -> PriorityInheritanceGuard<'_> {
// let current_task = task::get_my_current_task().unwrap();

// let mut current_priority = None;
// let mut other_priority = None;

// 'outer: for (core, run_queue) in RUNQUEUES.iter() {
// for epoch_task in run_queue.read().iter() {
// if epoch_task.task == current_task {
// current_priority = Some(epoch_task.priority);
// if other_priority.is_some() {
// break 'outer;
// }
// } else if &epoch_task.task == task {
// other_priority = Some((core, epoch_task.priority));
// if current_priority.is_some() {
// break 'outer;
// }
// }
// }
// }

// if let (Some(current_priority), Some((core, other_priority))) =
// (current_priority, other_priority) && current_priority >
// other_priority {
// // NOTE: This assumes no task migration.
// debug_assert!(RUNQUEUES.get(core).unwrap().write().set_priority(task,
// current_priority)); }

// PriorityInheritanceGuard {
// inner: if let (Some(current_priority), Some((_, other_priority))) =
// (current_priority, other_priority)
// && current_priority > other_priority
// {
// Some((task, other_priority))
// } else {
// None
// },
// }
// }
/// Modifies the given task's priority to be the maximum of its priority and the
/// current task's priority.
///
/// Returns a guard which reverts the change when dropped.
pub fn inherit_priority(task: &TaskRef) -> PriorityInheritanceGuard<'_> {
let current_task = super::get_my_current_task().unwrap();

let current_priority = priority(&current_task);
let other_priority = priority(task);

if let (Some(current_priority), Some(other_priority)) =
(current_priority, other_priority) && current_priority > other_priority
{
set_priority(task, current_priority);
}

PriorityInheritanceGuard {
inner: if let (Some(current_priority), Some(other_priority)) =
(current_priority, other_priority)
&& current_priority > other_priority
{
Some((task, other_priority))
} else {
None
},
}
}

/// Lowers the task's priority to its previous value when dropped.
pub struct PriorityInheritanceGuard<'a> {
inner: Option<(&'a TaskRef, u8)>,
}

impl<'a> Drop for PriorityInheritanceGuard<'a> {
fn drop(&mut self) {
if let Some((task, priority)) = self.inner {
set_priority(task, priority);
}
}
}

0 comments on commit 618b5ce

Please sign in to comment.