Skip to content
This repository was archived by the owner on Jul 6, 2019. It is now read-only.

Commit bf92f54

Browse files
committed
Scheduler now moves in Systick and StackManager
1 parent 7ed7236 commit bf92f54

File tree

1 file changed

+39
-27
lines changed

1 file changed

+39
-27
lines changed

src/os/sched/scheduler.rs

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,17 @@ use hal::systick::Systick;
3030
pub 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

3737
impl<'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)]
8686
mod 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

Comments
 (0)