@@ -30,18 +30,17 @@ use hal::systick::Systick;
30
30
pub struct Scheduler < ' a , T , S > {
31
31
index : task:: TasksIndex < ' a > ,
32
32
context_switch : ||: ' a ,
33
- systick : & ' a T ,
34
- stack_manager : & ' a S ,
33
+ systick : T ,
34
+ stack_manager : S ,
35
35
}
36
36
37
37
impl < ' a , T : Systick , S : StackManager > Scheduler < ' a , T , S > {
38
38
/// Creates a new scheduler given a list of tasks, systick timer and
39
39
/// management routines.
40
40
///
41
41
/// At least one task must be defined in task index.
42
- pub fn new ( ti : task:: TasksIndex < ' a > , systick : & ' a T ,
43
- stack_manager : & ' a S , ctx_switch: ||: ' a )
44
- -> Scheduler < ' a , T , S > {
42
+ pub fn new ( ti : task:: TasksIndex < ' a > , systick : T , stack_manager : S ,
43
+ ctx_switch: ||: ' a ) -> Scheduler < ' a , T , S > {
45
44
Scheduler {
46
45
index : ti,
47
46
context_switch : ctx_switch,
@@ -52,7 +51,8 @@ impl<'a, T: Systick, S: StackManager> Scheduler<'a, T, S> {
52
51
53
52
/// Starts a scheduler and switches to first task. Never returns.
54
53
pub fn start ( & mut self ) {
55
- self . stack_manager . set_task_stack_pointer ( self . index . tasks [ 0 ] . stack_start ) ;
54
+ self . stack_manager . set_task_stack_pointer (
55
+ self . index . tasks [ self . index . current_task_index as uint ] . stack_start ) ;
56
56
self . systick . start ( ) ;
57
57
( self . context_switch ) ( ) ;
58
58
}
@@ -85,7 +85,6 @@ impl<'a, T: Systick, S: StackManager> Scheduler<'a, T, S> {
85
85
#[ cfg( test) ]
86
86
mod test {
87
87
use hamcrest:: { assert_that, is, equal_to} ;
88
- use std:: cell:: Cell ;
89
88
use std:: kinds:: marker;
90
89
91
90
use hal:: systick:: Systick ;
@@ -94,34 +93,45 @@ mod test {
94
93
use super :: Scheduler ;
95
94
96
95
struct FakeSystick {
97
- pub started : Cell < bool >
96
+ started_ptr : * mut bool
98
97
}
99
98
100
99
impl FakeSystick {
101
- pub fn new ( ) -> FakeSystick { FakeSystick { started : Cell :: new ( false ) } }
100
+ pub fn new ( started : & mut bool ) -> FakeSystick {
101
+ FakeSystick {
102
+ started_ptr : started as * mut bool
103
+ }
104
+ }
102
105
}
103
106
impl Systick for FakeSystick {
104
- fn start ( & self ) { self . started . set ( true ) ; }
107
+ fn start ( & self ) {
108
+ unsafe { * self . started_ptr = true ; }
109
+ }
105
110
}
106
111
107
112
struct FakeStackManager {
108
- pub sp : Cell < u32 >
113
+ pub sp_ptr : * mut u32
109
114
}
110
115
impl FakeStackManager {
111
- pub fn new ( ) -> FakeStackManager { FakeStackManager { sp : Cell :: new ( 0 ) } }
116
+ pub fn new ( sp : & mut u32 ) -> FakeStackManager {
117
+ FakeStackManager {
118
+ sp_ptr : sp as * mut u32
119
+ }
120
+ }
112
121
}
113
122
impl StackManager for FakeStackManager {
114
123
fn get_task_stack_pointer ( & self ) -> u32 {
115
- self . sp . get ( )
124
+ unsafe { * self . sp_ptr }
116
125
}
117
126
fn set_task_stack_pointer ( & self , sp : u32 ) {
118
- self . sp . set ( sp ) ;
127
+ unsafe { * self . sp_ptr = sp ; }
119
128
}
120
129
}
121
130
122
131
describe ! (
123
132
before_each {
124
- let tick = FakeSystick :: new( ) ;
133
+ let mut systick_started = false ;
134
+ let tick = FakeSystick :: new( & mut systick_started) ;
125
135
let mut tasks = [ task:: Task {
126
136
state: task:: Runnable ,
127
137
stack_start: 100 ,
@@ -137,22 +147,23 @@ mod test {
137
147
current_task_index: 0 ,
138
148
no_copy: marker:: NoCopy ,
139
149
} ;
140
- let fsm = FakeStackManager :: new( ) ;
150
+ let mut sp = 0u32 ;
151
+ let fsm = FakeStackManager :: new( & mut sp) ;
141
152
}
142
153
143
154
it "calls a context switch with first task" {
144
155
let mut called = false ;
145
156
146
157
{
147
- let mut scheduler = Scheduler :: new( ti, & tick, & fsm, || { called = true } ) ;
158
+ let mut scheduler = Scheduler :: new( ti, tick, fsm, || { called = true } ) ;
148
159
scheduler. start( ) ;
149
160
}
150
161
151
162
assert_that( called, is( equal_to( true ) ) ) ;
152
163
}
153
164
154
165
it "schedules second task on timer interrupt" {
155
- let mut scheduler = Scheduler :: new( ti, & tick, & fsm, || { } ) ;
166
+ let mut scheduler = Scheduler :: new( ti, tick, fsm, || { } ) ;
156
167
scheduler. start( ) ;
157
168
158
169
scheduler. switch( ) ;
@@ -161,7 +172,7 @@ mod test {
161
172
}
162
173
163
174
it "wraps over to first task when all tasks are done" {
164
- let mut scheduler = Scheduler :: new( ti, & tick, & fsm, || { } ) ;
175
+ let mut scheduler = Scheduler :: new( ti, tick, fsm, || { } ) ;
165
176
scheduler. start( ) ;
166
177
167
178
scheduler. switch( ) ;
@@ -171,36 +182,37 @@ mod test {
171
182
}
172
183
173
184
it "enables systick timer on start" {
174
- let mut scheduler = Scheduler :: new( ti, & tick, & fsm, || { } ) ;
185
+ let mut scheduler = Scheduler :: new( ti, tick, fsm, || { } ) ;
175
186
scheduler. start( ) ;
176
187
177
- assert_that( tick . started . get ( ) , is( equal_to( true ) ) ) ;
188
+ assert_that( systick_started , is( equal_to( true ) ) ) ;
178
189
}
179
190
180
191
it "loads first task stack pointer" {
181
- let mut scheduler = Scheduler :: new( ti, & tick, & fsm, || { } ) ;
192
+ let mut scheduler = Scheduler :: new( ti, tick, fsm, || { } ) ;
182
193
scheduler. start( ) ;
183
194
184
- assert_that( fsm . sp . get ( ) , is( equal_to( 100u32 ) ) ) ;
195
+ assert_that( sp , is( equal_to( 100u32 ) ) ) ;
185
196
}
186
197
187
198
it "saves stack pointer to current task on switch" {
188
- let mut scheduler = Scheduler :: new( ti, & tick, & fsm, || { } ) ;
199
+ let mut scheduler = Scheduler :: new( ti, tick, fsm, || { } ) ;
189
200
scheduler. start( ) ;
190
201
191
- fsm . sp . set ( 110 ) ;
202
+ sp = 110 ;
192
203
scheduler. switch( ) ;
193
204
194
205
assert_that( scheduler. index( ) . tasks[ 0 ] . stack_start, is( equal_to( 110u32 ) ) ) ;
206
+ assert_that( sp, is( equal_to( 200u32 ) ) ) ;
195
207
}
196
208
197
209
it "loads stack pointer to next task on switch" {
198
- let mut scheduler = Scheduler :: new( ti, & tick, & fsm, || { } ) ;
210
+ let mut scheduler = Scheduler :: new( ti, tick, fsm, || { } ) ;
199
211
scheduler. start( ) ;
200
212
201
213
scheduler. switch( ) ;
202
214
203
- assert_that( fsm . sp . get ( ) , is( equal_to( 200u32 ) ) ) ;
215
+ assert_that( sp , is( equal_to( 200u32 ) ) ) ;
204
216
}
205
217
)
206
218
}
0 commit comments