Skip to content

Commit 3860d6c

Browse files
committed
protect access to a task by the closure irqsave
1 parent 88a5bca commit 3860d6c

File tree

1 file changed

+66
-48
lines changed

1 file changed

+66
-48
lines changed

src/scheduler/scheduler.rs

Lines changed: 66 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
// http://opensource.org/licenses/MIT>, at your option. This file may not be
66
// copied, modified, or distributed except according to those terms.
77

8-
use crate::arch::irq::{irq_nested_disable, irq_nested_enable};
98
use crate::arch::switch;
9+
use crate::collections::irqsave;
1010
use crate::consts::*;
1111
use crate::errno::*;
1212
use crate::logging::*;
@@ -61,37 +61,45 @@ impl Scheduler {
6161
}
6262

6363
pub fn spawn(&mut self, func: extern "C" fn(), prio: TaskPriority) -> Result<TaskId> {
64-
let prio_number = prio.into() as usize;
64+
let closure = || {
65+
let prio_number = prio.into() as usize;
6566

66-
if prio_number >= NO_PRIORITIES {
67-
return Err(Error::BadPriority);
68-
}
67+
if prio_number >= NO_PRIORITIES {
68+
return Err(Error::BadPriority);
69+
}
70+
71+
// Create the new task.
72+
let tid = self.get_tid();
73+
let task = Rc::new(RefCell::new(Task::new(tid, TaskStatus::TaskReady, prio)));
6974

70-
// Create the new task.
71-
let tid = self.get_tid();
72-
let task = Rc::new(RefCell::new(Task::new(tid, TaskStatus::TaskReady, prio)));
75+
task.borrow_mut().create_stack_frame(func);
7376

74-
task.borrow_mut().create_stack_frame(func);
77+
// Add it to the task lists.
78+
self.ready_queue.lock().push(task.clone());
79+
self.tasks.lock().insert(tid, task);
80+
NO_TASKS.fetch_add(1, Ordering::SeqCst);
7581

76-
// Add it to the task lists.
77-
self.ready_queue.lock().push(task.clone());
78-
self.tasks.lock().insert(tid, task);
79-
NO_TASKS.fetch_add(1, Ordering::SeqCst);
82+
info!("Creating task {}", tid);
8083

81-
info!("Creating task {}", tid);
84+
Ok(tid)
85+
};
8286

83-
Ok(tid)
87+
irqsave(closure)
8488
}
8589

8690
pub fn exit(&mut self) -> ! {
87-
if self.current_task.borrow().status != TaskStatus::TaskIdle {
88-
info!("finish task with id {}", self.current_task.borrow().id);
89-
self.current_task.borrow_mut().status = TaskStatus::TaskFinished;
90-
// update the number of tasks
91-
NO_TASKS.fetch_sub(1, Ordering::SeqCst);
92-
} else {
93-
panic!("unable to terminate idle task");
94-
}
91+
let closure = || {
92+
if self.current_task.borrow().status != TaskStatus::TaskIdle {
93+
info!("finish task with id {}", self.current_task.borrow().id);
94+
self.current_task.borrow_mut().status = TaskStatus::TaskFinished;
95+
// update the number of tasks
96+
NO_TASKS.fetch_sub(1, Ordering::SeqCst);
97+
} else {
98+
panic!("unable to terminate idle task");
99+
}
100+
};
101+
102+
irqsave(closure);
95103

96104
self.reschedule();
97105

@@ -100,14 +108,18 @@ impl Scheduler {
100108
}
101109

102110
pub fn abort(&mut self) -> ! {
103-
if self.current_task.borrow().status != TaskStatus::TaskIdle {
104-
info!("abort task with id {}", self.current_task.borrow().id);
105-
self.current_task.borrow_mut().status = TaskStatus::TaskFinished;
106-
// update the number of tasks
107-
NO_TASKS.fetch_sub(1, Ordering::SeqCst);
108-
} else {
109-
panic!("unable to terminate idle task");
110-
}
111+
let closure = || {
112+
if self.current_task.borrow().status != TaskStatus::TaskIdle {
113+
info!("abort task with id {}", self.current_task.borrow().id);
114+
self.current_task.borrow_mut().status = TaskStatus::TaskFinished;
115+
// update the number of tasks
116+
NO_TASKS.fetch_sub(1, Ordering::SeqCst);
117+
} else {
118+
panic!("unable to terminate idle task");
119+
}
120+
};
121+
122+
irqsave(closure);
111123

112124
self.reschedule();
113125

@@ -116,32 +128,40 @@ impl Scheduler {
116128
}
117129

118130
pub fn block_current_task(&mut self) -> Rc<RefCell<Task>> {
119-
if self.current_task.borrow().status == TaskStatus::TaskRunning {
120-
debug!("block task {}", self.current_task.borrow().id);
131+
let closure = || {
132+
if self.current_task.borrow().status == TaskStatus::TaskRunning {
133+
debug!("block task {}", self.current_task.borrow().id);
134+
135+
self.current_task.borrow_mut().status = TaskStatus::TaskBlocked;
136+
self.current_task.clone()
137+
} else {
138+
panic!("unable to block task {}", self.current_task.borrow().id);
139+
}
140+
};
121141

122-
self.current_task.borrow_mut().status = TaskStatus::TaskBlocked;
123-
self.current_task.clone()
124-
} else {
125-
panic!("unable to block task {}", self.current_task.borrow().id);
126-
}
142+
irqsave(closure)
127143
}
128144

129145
pub fn wakeup_task(&mut self, task: Rc<RefCell<Task>>) {
130-
if task.borrow().status == TaskStatus::TaskBlocked {
131-
debug!("wakeup task {}", task.borrow().id);
146+
let closure = || {
147+
if task.borrow().status == TaskStatus::TaskBlocked {
148+
debug!("wakeup task {}", task.borrow().id);
132149

133-
task.borrow_mut().status = TaskStatus::TaskReady;
134-
self.ready_queue.lock().push(task.clone());
135-
}
150+
task.borrow_mut().status = TaskStatus::TaskReady;
151+
self.ready_queue.lock().push(task.clone());
152+
}
153+
};
154+
155+
irqsave(closure);
136156
}
137157

138158
pub fn get_current_taskid(&self) -> TaskId {
139-
self.current_task.borrow().id
159+
irqsave(|| self.current_task.borrow().id)
140160
}
141161

142162
/// Determines the start address of the stack
143163
pub fn get_current_stack(&self) -> usize {
144-
unsafe { (*self.current_task.borrow().stack).bottom() }
164+
irqsave(|| unsafe { (*self.current_task.borrow().stack).bottom() })
145165
}
146166

147167
pub fn schedule(&mut self) {
@@ -221,8 +241,6 @@ impl Scheduler {
221241
}
222242

223243
pub fn reschedule(&mut self) {
224-
let flags = irq_nested_disable();
225-
self.schedule();
226-
irq_nested_enable(flags);
244+
irqsave(|| self.schedule());
227245
}
228246
}

0 commit comments

Comments
 (0)