@@ -30,18 +30,17 @@ use hal::systick::Systick;
3030pub struct Scheduler < ' a , T , S > {
3131 index : task:: TasksIndex < ' a > ,
3232 context_switch : ||: ' a ,
33- systick : & ' a T ,
34- stack_manager : & ' a S ,
33+ systick : T ,
34+ stack_manager : S ,
3535}
3636
3737impl < ' a , T : Systick , S : StackManager > Scheduler < ' a , T , S > {
3838 /// Creates a new scheduler given a list of tasks, systick timer and
3939 /// management routines.
4040 ///
4141 /// 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 > {
4544 Scheduler {
4645 index : ti,
4746 context_switch : ctx_switch,
@@ -52,7 +51,8 @@ impl<'a, T: Systick, S: StackManager> Scheduler<'a, T, S> {
5251
5352 /// Starts a scheduler and switches to first task. Never returns.
5453 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 ) ;
5656 self . systick . start ( ) ;
5757 ( self . context_switch ) ( ) ;
5858 }
@@ -85,7 +85,6 @@ impl<'a, T: Systick, S: StackManager> Scheduler<'a, T, S> {
8585#[ cfg( test) ]
8686mod test {
8787 use hamcrest:: { assert_that, is, equal_to} ;
88- use std:: cell:: Cell ;
8988 use std:: kinds:: marker;
9089
9190 use hal:: systick:: Systick ;
@@ -94,34 +93,45 @@ mod test {
9493 use super :: Scheduler ;
9594
9695 struct FakeSystick {
97- pub started : Cell < bool >
96+ started_ptr : * mut bool
9897 }
9998
10099 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+ }
102105 }
103106 impl Systick for FakeSystick {
104- fn start ( & self ) { self . started . set ( true ) ; }
107+ fn start ( & self ) {
108+ unsafe { * self . started_ptr = true ; }
109+ }
105110 }
106111
107112 struct FakeStackManager {
108- pub sp : Cell < u32 >
113+ pub sp_ptr : * mut u32
109114 }
110115 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+ }
112121 }
113122 impl StackManager for FakeStackManager {
114123 fn get_task_stack_pointer ( & self ) -> u32 {
115- self . sp . get ( )
124+ unsafe { * self . sp_ptr }
116125 }
117126 fn set_task_stack_pointer ( & self , sp : u32 ) {
118- self . sp . set ( sp ) ;
127+ unsafe { * self . sp_ptr = sp ; }
119128 }
120129 }
121130
122131 describe ! (
123132 before_each {
124- let tick = FakeSystick :: new( ) ;
133+ let mut systick_started = false ;
134+ let tick = FakeSystick :: new( & mut systick_started) ;
125135 let mut tasks = [ task:: Task {
126136 state: task:: Runnable ,
127137 stack_start: 100 ,
@@ -137,22 +147,23 @@ mod test {
137147 current_task_index: 0 ,
138148 no_copy: marker:: NoCopy ,
139149 } ;
140- let fsm = FakeStackManager :: new( ) ;
150+ let mut sp = 0u32 ;
151+ let fsm = FakeStackManager :: new( & mut sp) ;
141152 }
142153
143154 it "calls a context switch with first task" {
144155 let mut called = false ;
145156
146157 {
147- let mut scheduler = Scheduler :: new( ti, & tick, & fsm, || { called = true } ) ;
158+ let mut scheduler = Scheduler :: new( ti, tick, fsm, || { called = true } ) ;
148159 scheduler. start( ) ;
149160 }
150161
151162 assert_that( called, is( equal_to( true ) ) ) ;
152163 }
153164
154165 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, || { } ) ;
156167 scheduler. start( ) ;
157168
158169 scheduler. switch( ) ;
@@ -161,7 +172,7 @@ mod test {
161172 }
162173
163174 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, || { } ) ;
165176 scheduler. start( ) ;
166177
167178 scheduler. switch( ) ;
@@ -171,36 +182,37 @@ mod test {
171182 }
172183
173184 it "enables systick timer on start" {
174- let mut scheduler = Scheduler :: new( ti, & tick, & fsm, || { } ) ;
185+ let mut scheduler = Scheduler :: new( ti, tick, fsm, || { } ) ;
175186 scheduler. start( ) ;
176187
177- assert_that( tick . started . get ( ) , is( equal_to( true ) ) ) ;
188+ assert_that( systick_started , is( equal_to( true ) ) ) ;
178189 }
179190
180191 it "loads first task stack pointer" {
181- let mut scheduler = Scheduler :: new( ti, & tick, & fsm, || { } ) ;
192+ let mut scheduler = Scheduler :: new( ti, tick, fsm, || { } ) ;
182193 scheduler. start( ) ;
183194
184- assert_that( fsm . sp . get ( ) , is( equal_to( 100u32 ) ) ) ;
195+ assert_that( sp , is( equal_to( 100u32 ) ) ) ;
185196 }
186197
187198 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, || { } ) ;
189200 scheduler. start( ) ;
190201
191- fsm . sp . set ( 110 ) ;
202+ sp = 110 ;
192203 scheduler. switch( ) ;
193204
194205 assert_that( scheduler. index( ) . tasks[ 0 ] . stack_start, is( equal_to( 110u32 ) ) ) ;
206+ assert_that( sp, is( equal_to( 200u32 ) ) ) ;
195207 }
196208
197209 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, || { } ) ;
199211 scheduler. start( ) ;
200212
201213 scheduler. switch( ) ;
202214
203- assert_that( fsm . sp . get ( ) , is( equal_to( 200u32 ) ) ) ;
215+ assert_that( sp , is( equal_to( 200u32 ) ) ) ;
204216 }
205217 )
206218}
0 commit comments