1
- //! Runqueue structures for a realtime scheduler using rate monotonic scheduling .
1
+ //! Runqueue structures for a priority scheduler.
2
2
//!
3
3
//! 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`
5
5
//! 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.
18
6
19
7
#![ no_std]
20
8
@@ -30,36 +18,36 @@ use alloc::collections::VecDeque;
30
18
use core:: ops:: { Deref , DerefMut } ;
31
19
use atomic_linked_list:: atomic_map:: AtomicMap ;
32
20
33
- /// A reference to a task with its period for realtime scheduling.
21
+ /// A reference to a task with its period for priority scheduling.
34
22
///
35
- /// `RealtimeTaskRef ` implements `Deref` and `DerefMut` traits, which dereferences to `TaskRef`.
23
+ /// `PriorityTaskRef ` implements `Deref` and `DerefMut` traits, which dereferences to `TaskRef`.
36
24
#[ derive( Debug , Clone ) ]
37
- pub struct RealtimeTaskRef {
38
- /// `TaskRef` wrapped by `RealtimeTaskRef `
25
+ pub struct PriorityTaskRef {
26
+ /// `TaskRef` wrapped by `PriorityTaskRef `
39
27
taskref : TaskRef ,
40
28
/// `Some` if the task is periodic, `None` if it is aperiodic.
41
29
period : Option < usize > ,
42
30
/// Number of context switches the task has undergone. Not used in scheduling algorithm
43
31
context_switches : usize ,
44
32
}
45
33
46
- impl Deref for RealtimeTaskRef {
34
+ impl Deref for PriorityTaskRef {
47
35
type Target = TaskRef ;
48
36
fn deref ( & self ) -> & TaskRef {
49
37
& self . taskref
50
38
}
51
39
}
52
40
53
- impl DerefMut for RealtimeTaskRef {
41
+ impl DerefMut for PriorityTaskRef {
54
42
fn deref_mut ( & mut self ) -> & mut TaskRef {
55
43
& mut self . taskref
56
44
}
57
45
}
58
46
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 {
63
51
taskref,
64
52
period,
65
53
context_switches : 0 ,
@@ -71,17 +59,17 @@ impl RealtimeTaskRef {
71
59
self . context_switches = self . context_switches . saturating_add ( 1 ) ;
72
60
}
73
61
74
- /// Checks whether the `RealtimeTaskRef ` refers to a task that is periodic
62
+ /// Checks whether the `PriorityTaskRef ` refers to a task that is periodic
75
63
pub fn is_periodic ( & self ) -> bool {
76
64
self . period . is_some ( )
77
65
}
78
66
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 `.
81
69
///
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`.
83
71
/// 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 {
85
73
match self . period {
86
74
Some ( period_val) => if let Some ( other_period_val) = other. period {
87
75
period_val < other_period_val
@@ -97,47 +85,47 @@ impl RealtimeTaskRef {
97
85
/// and allows the scheduler to select a task from that runqueue to schedule in
98
86
static RUNQUEUES : AtomicMap < u8 , PreemptionSafeRwLock < RunQueue > > = AtomicMap :: new ( ) ;
99
87
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.
101
89
///
102
90
/// In rate monotonic scheduling, tasks are sorted in order of increasing periods.
103
91
/// Thus, the `period` value acts as a form of task "priority",
104
92
/// with higher priority (shorter period) tasks coming first.
105
93
#[ derive( Debug ) ]
106
94
pub struct RunQueue {
107
95
core : u8 ,
108
- queue : VecDeque < RealtimeTaskRef > ,
96
+ queue : VecDeque < PriorityTaskRef > ,
109
97
}
110
98
111
99
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 > {
114
102
& self . queue
115
103
}
116
104
}
117
105
118
106
impl DerefMut for RunQueue {
119
- fn deref_mut ( & mut self ) -> & mut VecDeque < RealtimeTaskRef > {
107
+ fn deref_mut ( & mut self ) -> & mut VecDeque < PriorityTaskRef > {
120
108
& mut self . queue
121
109
}
122
110
}
123
111
124
112
125
113
impl RunQueue {
126
- /// Moves the `RealtimeTaskRef ` at the given `index` in this `RunQueue`
114
+ /// Moves the `PriorityTaskRef ` at the given `index` in this `RunQueue`
127
115
/// to the appropriate location in this `RunQueue` based on its period.
128
116
///
129
117
/// Returns a reference to the underlying `Task`.
130
118
///
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`
133
121
/// in order to ensure no aperiodic tasks are selected until there are no periodic tasks ready for execution.
134
122
/// Afterwards, the number of context switches is incremented by one.
135
123
/// This function is used when the task is selected by the scheduler.
136
124
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 ) ;
141
129
Some ( taskref)
142
130
}
143
131
else {
@@ -148,7 +136,7 @@ impl RunQueue {
148
136
/// Creates a new `RunQueue` for the given core, which is an `apic_id`
149
137
pub fn init ( which_core : u8 ) -> Result < ( ) , & ' static str > {
150
138
#[ cfg( not( loscd_eval) ) ]
151
- trace ! ( "Created runqueue (realtime ) for core {}" , which_core) ;
139
+ trace ! ( "Created runqueue (priority ) for core {}" , which_core) ;
152
140
let new_rq = PreemptionSafeRwLock :: new ( RunQueue {
153
141
core : which_core,
154
142
queue : VecDeque :: new ( ) ,
@@ -213,11 +201,11 @@ impl RunQueue {
213
201
. add_task ( task, None )
214
202
}
215
203
216
- /// Inserts a `RealtimeTaskRef ` at its proper position in the queue.
204
+ /// Inserts a `PriorityTaskRef ` at its proper position in the queue.
217
205
///
218
206
/// Under the RMS scheduling algorithm, tasks should be sorted in increasing value
219
207
/// 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 ) {
221
209
match taskref. period {
222
210
None => self . push_back ( taskref) ,
223
211
Some ( _) => {
@@ -244,16 +232,16 @@ impl RunQueue {
244
232
245
233
/// Adds a `TaskRef` to this runqueue with the given periodicity value
246
234
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 ) ;
250
238
251
239
Ok ( ( ) )
252
240
}
253
241
254
242
/// The internal function that actually removes the task from the runqueue.
255
243
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) ;
257
245
self . retain ( |x| & x. taskref != task) ;
258
246
259
247
Ok ( ( ) )
@@ -275,16 +263,16 @@ impl RunQueue {
275
263
}
276
264
277
265
/// 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
279
267
fn set_periodicity_internal (
280
268
& mut self ,
281
269
task : & TaskRef ,
282
270
period : usize
283
271
) -> Result < ( ) , & ' static str > {
284
272
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 ) ;
288
276
}
289
277
} ;
290
278
Ok ( ( ) )
0 commit comments