Skip to content

Commit d91bb44

Browse files
authored
Rename scheduler_realtime to scheduler_priority (theseus-os#981)
The realtime scheduler doesn't actually implement rate monotonic scheduling as the period is used as a glorified inverse priority. See theseus-os#980. Signed-off-by: Klimenty Tsoutsman <klim@tsoutsman.com>
1 parent e6e255f commit d91bb44

File tree

13 files changed

+83
-96
lines changed

13 files changed

+83
-96
lines changed

Cargo.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ exclude = [
8888
"applications/test_mlx5",
8989
"applications/test_mutex_sleep",
9090
"applications/test_panic",
91-
"applications/test_realtime",
91+
"applications/test_priority_scheduler",
9292
"applications/test_restartable",
9393
"applications/test_serial_echo",
9494
"applications/test_std_fs",

applications/test_realtime/Cargo.toml renamed to applications/test_priority_scheduler/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
2-
name = "test_realtime"
2+
name = "test_priority_scheduler"
33
version = "0.1.0"
4-
description = "Application to test scheduling of periodic tasks."
4+
description = "Application to test the priority scheduler"
55
authors = ["Jacob Earle <earlejacobt@gmail.com>"]
66

77
[dependencies]

applications/test_realtime/src/lib.rs renamed to applications/test_priority_scheduler/src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! Demo of scheduling a periodic task using the realtime scheduler.
1+
//! Demo of scheduling a periodic task using the priority scheduler.
22
//!
33
//! One potential direction for future testing could be the following:
44
//! Let the program take in arguments `n` and `p1` ... `pm`.
@@ -27,12 +27,12 @@ use alloc::{
2727
};
2828

2929
pub fn main(_args: Vec<String>) -> isize {
30-
#[cfg(not(realtime_scheduler))] {
31-
println!("Error: `realtime_scheduler` cfg was not enabled!");
30+
#[cfg(not(priority_scheduler))] {
31+
println!("Error: `priority_scheduler` cfg was not enabled!");
3232
-1
3333
}
34-
#[cfg(realtime_scheduler)] {
35-
println!("Testing periodic task(s) with the realtime scheduler!");
34+
#[cfg(priority_scheduler)] {
35+
println!("Testing periodic task(s) with the priority scheduler!");
3636
// Build and spawn two real time periodic task(s).
3737
// Start them as blocked in order to set the periods before they run
3838
let periodic_tb1 = spawn::new_task_builder(_task_delay_tester, 1).block();

kernel/runqueue/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ path = "../runqueue_round_robin"
3131
[dependencies.runqueue_epoch]
3232
path = "../runqueue_epoch"
3333

34-
[dependencies.runqueue_realtime]
35-
path = "../runqueue_realtime"
34+
[dependencies.runqueue_priority]
35+
path = "../runqueue_priority"
3636

3737
## This should be dependent upon 'cfg(single_simd_task_optimization)',
3838
## but it cannot be because of https://github.com/rust-lang/cargo/issues/5499.

kernel/runqueue/src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! This crate contains the API of the `RunQueue` structure, Runqueue Structure should contain
22
//! list of tasks with additional scheduling information depending on the scheduler.
33
//! All crates except the scheduler should refer to this crate to access functions on `RunQueue`.
4-
//!
54
65
#![no_std]
76

@@ -13,8 +12,8 @@ extern crate task;
1312
cfg_if! {
1413
if #[cfg(epoch_scheduler)] {
1514
extern crate runqueue_epoch as runqueue;
16-
} else if #[cfg(realtime_scheduler)] {
17-
extern crate runqueue_realtime as runqueue;
15+
} else if #[cfg(priority_scheduler)] {
16+
extern crate runqueue_priority as runqueue;
1817
} else {
1918
extern crate runqueue_round_robin as runqueue;
2019
}

kernel/runqueue_realtime/Cargo.toml renamed to kernel/runqueue_priority/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
authors = ["Jacob Earle <earlejacobt@gmail.com>"]
3-
name = "runqueue_realtime"
4-
description = "Functions and types for handling runqueues in a realtime scheduling context"
3+
name = "runqueue_priority"
4+
description = "Functions and types for handling runqueues in a priority scheduling context"
55
version = "0.1.0"
66

77
[dependencies.task]

kernel/runqueue_realtime/src/lib.rs renamed to kernel/runqueue_priority/src/lib.rs

Lines changed: 40 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,8 @@
1-
//! Runqueue structures for a realtime scheduler using rate monotonic scheduling.
1+
//! Runqueue structures for a priority scheduler.
22
//!
33
//! The `RunQueue` structure is essentially a list of `Task`s used for scheduling purposes.
4-
//! Each `RealtimeTaskRef` element in the runqueue contains a `TaskRef`
4+
//! Each `PriorityTaskRef` element in the runqueue contains a `TaskRef`
55
//! representing an underlying task and as well as a `period` value.
6-
//!
7-
//! In rate monotonic scheduling, tasks are assigned fixed priorities in order of increasing periods.
8-
//! Thus, the `period` value of a `RealtimeTaskRef` acts as a form of priority.
9-
//! Each `RunQueue` consists of a `VecDeque` of `RealtimeTaskRef`s
10-
//! sorted in increasing order of their `period` values.
11-
//! The sorting is maintained by inserting each `RealtimeTaskRef` at the proper index
12-
//! according to its `period` value.
13-
//!
14-
//! Aperiodic tasks are assigned a `period` value of `None` and are placed at the back of the queue.
15-
//! Since the scheduler iterates through the runqueue to select the first `Runnable` task,
16-
//! lower-period tasks are "higher priority" and will be selected first,
17-
//! with aperiodic tasks being selected only when no periodic tasks are runnable.
186
197
#![no_std]
208

@@ -30,36 +18,36 @@ use alloc::collections::VecDeque;
3018
use core::ops::{Deref, DerefMut};
3119
use atomic_linked_list::atomic_map::AtomicMap;
3220

33-
/// A reference to a task with its period for realtime scheduling.
21+
/// A reference to a task with its period for priority scheduling.
3422
///
35-
/// `RealtimeTaskRef` implements `Deref` and `DerefMut` traits, which dereferences to `TaskRef`.
23+
/// `PriorityTaskRef` implements `Deref` and `DerefMut` traits, which dereferences to `TaskRef`.
3624
#[derive(Debug, Clone)]
37-
pub struct RealtimeTaskRef {
38-
/// `TaskRef` wrapped by `RealtimeTaskRef`
25+
pub struct PriorityTaskRef {
26+
/// `TaskRef` wrapped by `PriorityTaskRef`
3927
taskref: TaskRef,
4028
/// `Some` if the task is periodic, `None` if it is aperiodic.
4129
period: Option<usize>,
4230
/// Number of context switches the task has undergone. Not used in scheduling algorithm
4331
context_switches: usize,
4432
}
4533

46-
impl Deref for RealtimeTaskRef {
34+
impl Deref for PriorityTaskRef {
4735
type Target = TaskRef;
4836
fn deref(&self) -> &TaskRef {
4937
&self.taskref
5038
}
5139
}
5240

53-
impl DerefMut for RealtimeTaskRef {
41+
impl DerefMut for PriorityTaskRef {
5442
fn deref_mut(&mut self) -> &mut TaskRef {
5543
&mut self.taskref
5644
}
5745
}
5846

59-
impl RealtimeTaskRef {
60-
/// Creates a new `RealtimeTaskRef` that wraps the given `TaskRef`
61-
pub fn new(taskref: TaskRef, period: Option<usize>) -> RealtimeTaskRef {
62-
RealtimeTaskRef {
47+
impl PriorityTaskRef {
48+
/// Creates a new `PriorityTaskRef` that wraps the given `TaskRef`
49+
pub fn new(taskref: TaskRef, period: Option<usize>) -> PriorityTaskRef {
50+
PriorityTaskRef {
6351
taskref,
6452
period,
6553
context_switches: 0,
@@ -71,17 +59,17 @@ impl RealtimeTaskRef {
7159
self.context_switches = self.context_switches.saturating_add(1);
7260
}
7361

74-
/// Checks whether the `RealtimeTaskRef` refers to a task that is periodic
62+
/// Checks whether the `PriorityTaskRef` refers to a task that is periodic
7563
pub fn is_periodic(&self) -> bool {
7664
self.period.is_some()
7765
}
7866

79-
/// Returns `true` if the period of this `RealtimeTaskRef` is shorter (less) than
80-
/// the period of the other `RealtimeTaskRef`.
67+
/// Returns `true` if the period of this `PriorityTaskRef` is shorter (less) than
68+
/// the period of the other `PriorityTaskRef`.
8169
///
82-
/// Returns `false` if this `RealtimeTaskRef` is aperiodic, i.e. if `period` is `None`.
70+
/// Returns `false` if this `PriorityTaskRef` is aperiodic, i.e. if `period` is `None`.
8371
/// Returns `true` if this task is periodic and `other` is aperiodic.
84-
pub fn has_smaller_period(&self, other: &RealtimeTaskRef) -> bool {
72+
pub fn has_smaller_period(&self, other: &PriorityTaskRef) -> bool {
8573
match self.period {
8674
Some(period_val) => if let Some(other_period_val) = other.period {
8775
period_val < other_period_val
@@ -97,47 +85,47 @@ impl RealtimeTaskRef {
9785
/// and allows the scheduler to select a task from that runqueue to schedule in
9886
static RUNQUEUES: AtomicMap<u8, PreemptionSafeRwLock<RunQueue>> = AtomicMap::new();
9987

100-
/// A list of `Task`s and their associated realtime scheduler data that may be run on a given CPU core.
88+
/// A list of `Task`s and their associated priority scheduler data that may be run on a given CPU core.
10189
///
10290
/// In rate monotonic scheduling, tasks are sorted in order of increasing periods.
10391
/// Thus, the `period` value acts as a form of task "priority",
10492
/// with higher priority (shorter period) tasks coming first.
10593
#[derive(Debug)]
10694
pub struct RunQueue {
10795
core: u8,
108-
queue: VecDeque<RealtimeTaskRef>,
96+
queue: VecDeque<PriorityTaskRef>,
10997
}
11098

11199
impl Deref for RunQueue {
112-
type Target = VecDeque<RealtimeTaskRef>;
113-
fn deref(&self) -> &VecDeque<RealtimeTaskRef> {
100+
type Target = VecDeque<PriorityTaskRef>;
101+
fn deref(&self) -> &VecDeque<PriorityTaskRef> {
114102
&self.queue
115103
}
116104
}
117105

118106
impl DerefMut for RunQueue {
119-
fn deref_mut(&mut self) -> &mut VecDeque<RealtimeTaskRef> {
107+
fn deref_mut(&mut self) -> &mut VecDeque<PriorityTaskRef> {
120108
&mut self.queue
121109
}
122110
}
123111

124112

125113
impl RunQueue {
126-
/// Moves the `RealtimeTaskRef` at the given `index` in this `RunQueue`
114+
/// Moves the `PriorityTaskRef` at the given `index` in this `RunQueue`
127115
/// to the appropriate location in this `RunQueue` based on its period.
128116
///
129117
/// Returns a reference to the underlying `Task`.
130118
///
131-
/// Thus, the `RealtimeTaskRef will be reinserted into the `RunQueue` so the `RunQueue` contains the
132-
/// `RealtimeTaskRef`s in order of increasing period. All aperiodic tasks will simply be reinserted at the end of the `RunQueue`
119+
/// Thus, the `PriorityTaskRef will be reinserted into the `RunQueue` so the `RunQueue` contains the
120+
/// `PriorityTaskRef`s in order of increasing period. All aperiodic tasks will simply be reinserted at the end of the `RunQueue`
133121
/// in order to ensure no aperiodic tasks are selected until there are no periodic tasks ready for execution.
134122
/// Afterwards, the number of context switches is incremented by one.
135123
/// This function is used when the task is selected by the scheduler.
136124
pub fn update_and_reinsert(&mut self, index: usize) -> Option<TaskRef> {
137-
if let Some(mut realtime_taskref) = self.remove(index) {
138-
realtime_taskref.increment_context_switches();
139-
let taskref = realtime_taskref.taskref.clone();
140-
self.insert_realtime_taskref_at_proper_location(realtime_taskref);
125+
if let Some(mut priority_taskref) = self.remove(index) {
126+
priority_taskref.increment_context_switches();
127+
let taskref = priority_taskref.taskref.clone();
128+
self.insert_priority_taskref_at_proper_location(priority_taskref);
141129
Some(taskref)
142130
}
143131
else {
@@ -148,7 +136,7 @@ impl RunQueue {
148136
/// Creates a new `RunQueue` for the given core, which is an `apic_id`
149137
pub fn init(which_core: u8) -> Result<(), &'static str> {
150138
#[cfg(not(loscd_eval))]
151-
trace!("Created runqueue (realtime) for core {}", which_core);
139+
trace!("Created runqueue (priority) for core {}", which_core);
152140
let new_rq = PreemptionSafeRwLock::new(RunQueue {
153141
core: which_core,
154142
queue: VecDeque::new(),
@@ -213,11 +201,11 @@ impl RunQueue {
213201
.add_task(task, None)
214202
}
215203

216-
/// Inserts a `RealtimeTaskRef` at its proper position in the queue.
204+
/// Inserts a `PriorityTaskRef` at its proper position in the queue.
217205
///
218206
/// Under the RMS scheduling algorithm, tasks should be sorted in increasing value
219207
/// of their periods, with aperiodic tasks being placed at the end.
220-
fn insert_realtime_taskref_at_proper_location(&mut self, taskref: RealtimeTaskRef) {
208+
fn insert_priority_taskref_at_proper_location(&mut self, taskref: PriorityTaskRef) {
221209
match taskref.period {
222210
None => self.push_back(taskref),
223211
Some(_) => {
@@ -244,16 +232,16 @@ impl RunQueue {
244232

245233
/// Adds a `TaskRef` to this runqueue with the given periodicity value
246234
fn add_task(&mut self, task: TaskRef, period: Option<usize>) -> Result<(), &'static str> {
247-
debug!("Adding task to runqueue_realtime {}, {:?}", self.core, task);
248-
let realtime_taskref = RealtimeTaskRef::new(task, period);
249-
self.insert_realtime_taskref_at_proper_location(realtime_taskref);
235+
debug!("Adding task to runqueue_priority {}, {:?}", self.core, task);
236+
let priority_taskref = PriorityTaskRef::new(task, period);
237+
self.insert_priority_taskref_at_proper_location(priority_taskref);
250238

251239
Ok(())
252240
}
253241

254242
/// The internal function that actually removes the task from the runqueue.
255243
fn remove_internal(&mut self, task: &TaskRef) -> Result<(), &'static str> {
256-
debug!("Removing task from runqueue_realtime {}, {:?}", self.core, task);
244+
debug!("Removing task from runqueue_priority {}, {:?}", self.core, task);
257245
self.retain(|x| &x.taskref != task);
258246

259247
Ok(())
@@ -275,16 +263,16 @@ impl RunQueue {
275263
}
276264

277265
/// The internal function that sets the periodicity of a given `Task` in a single `RunQueue`
278-
/// then reinserts the `RealtimeTaskRef` at the proper location
266+
/// then reinserts the `PriorityTaskRef` at the proper location
279267
fn set_periodicity_internal(
280268
&mut self,
281269
task: &TaskRef,
282270
period: usize
283271
) -> Result<(), &'static str> {
284272
if let Some(i) = self.iter().position(|rt| &rt.taskref == task) {
285-
if let Some(mut realtime_taskref) = self.remove(i) {
286-
realtime_taskref.period = Some(period);
287-
self.insert_realtime_taskref_at_proper_location(realtime_taskref);
273+
if let Some(mut priority_taskref) = self.remove(i) {
274+
priority_taskref.period = Some(period);
275+
self.insert_priority_taskref_at_proper_location(priority_taskref);
288276
}
289277
};
290278
Ok(())

kernel/scheduler/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ task = { path = "../task" }
1717

1818
scheduler_round_robin = { path = "../scheduler_round_robin" }
1919
scheduler_epoch = { path = "../scheduler_epoch" }
20-
scheduler_realtime = { path = "../scheduler_realtime" }
20+
scheduler_priority = { path = "../scheduler_priority" }
2121

2222
[target.'cfg(target_arch = "x86_64")'.dependencies]
2323
x86_64 = "0.14.8"

0 commit comments

Comments
 (0)