Skip to content

Commit c6ed580

Browse files
committed
protect access to a task by the closure irqsave
1 parent 803596d commit c6ed580

File tree

1 file changed

+62
-44
lines changed

1 file changed

+62
-44
lines changed

src/scheduler/scheduler.rs

Lines changed: 62 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
// copied, modified, or distributed except according to those terms.
77

88
use crate::arch::drop_user_space;
9-
use crate::arch::irq::{irq_nested_disable, irq_nested_enable};
109
use crate::arch::switch;
10+
use crate::collections::irqsave;
1111
use crate::consts::*;
1212
use crate::errno::*;
1313
use crate::logging::*;
@@ -62,26 +62,30 @@ impl Scheduler {
6262
}
6363

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

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

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

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

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);
83+
info!("Creating task {}", tid);
8184

82-
info!("Creating task {}", tid);
85+
Ok(tid)
86+
};
8387

84-
Ok(tid)
88+
irqsave(closure)
8589
}
8690

8791
fn cleanup(&mut self) {
@@ -95,12 +99,16 @@ impl Scheduler {
9599
}
96100

97101
pub fn exit(&mut self) -> ! {
98-
if self.current_task.borrow().status != TaskStatus::TaskIdle {
99-
info!("finish task with id {}", self.current_task.borrow().id);
100-
self.cleanup();
101-
} else {
102-
panic!("unable to terminate idle task");
103-
}
102+
let closure = || {
103+
if self.current_task.borrow().status != TaskStatus::TaskIdle {
104+
info!("finish task with id {}", self.current_task.borrow().id);
105+
self.cleanup();
106+
} else {
107+
panic!("unable to terminate idle task");
108+
}
109+
};
110+
111+
irqsave(closure);
104112

105113
self.reschedule();
106114

@@ -109,12 +117,16 @@ impl Scheduler {
109117
}
110118

111119
pub fn abort(&mut self) -> ! {
112-
if self.current_task.borrow().status != TaskStatus::TaskIdle {
113-
info!("abort task with id {}", self.current_task.borrow().id);
114-
self.cleanup();
115-
} else {
116-
panic!("unable to terminate idle task");
117-
}
120+
let closure = || {
121+
if self.current_task.borrow().status != TaskStatus::TaskIdle {
122+
info!("abort task with id {}", self.current_task.borrow().id);
123+
self.cleanup();
124+
} else {
125+
panic!("unable to terminate idle task");
126+
}
127+
};
128+
129+
irqsave(closure);
118130

119131
self.reschedule();
120132

@@ -123,33 +135,41 @@ impl Scheduler {
123135
}
124136

125137
pub fn block_current_task(&mut self) -> Rc<RefCell<Task>> {
126-
if self.current_task.borrow().status == TaskStatus::TaskRunning {
127-
debug!("block task {}", self.current_task.borrow().id);
138+
let closure = || {
139+
if self.current_task.borrow().status == TaskStatus::TaskRunning {
140+
debug!("block task {}", self.current_task.borrow().id);
141+
142+
self.current_task.borrow_mut().status = TaskStatus::TaskBlocked;
143+
self.current_task.clone()
144+
} else {
145+
panic!("unable to block task {}", self.current_task.borrow().id);
146+
}
147+
};
128148

129-
self.current_task.borrow_mut().status = TaskStatus::TaskBlocked;
130-
self.current_task.clone()
131-
} else {
132-
panic!("unable to block task {}", self.current_task.borrow().id);
133-
}
149+
irqsave(closure)
134150
}
135151

136152
pub fn wakeup_task(&mut self, task: Rc<RefCell<Task>>) {
137-
if task.borrow().status == TaskStatus::TaskBlocked {
138-
debug!("wakeup task {}", task.borrow().id);
153+
let closure = || {
154+
if task.borrow().status == TaskStatus::TaskBlocked {
155+
debug!("wakeup task {}", task.borrow().id);
139156

140-
task.borrow_mut().status = TaskStatus::TaskReady;
141-
self.ready_queue.lock().push(task.clone());
142-
}
157+
task.borrow_mut().status = TaskStatus::TaskReady;
158+
self.ready_queue.lock().push(task.clone());
159+
}
160+
};
161+
162+
irqsave(closure);
143163
}
144164

145165
pub fn get_current_taskid(&self) -> TaskId {
146-
self.current_task.borrow().id
166+
irqsave(|| self.current_task.borrow().id)
147167
}
148168

149169
/// Determines the start address of the stack
150170
#[no_mangle]
151171
pub fn get_current_stack(&self) -> usize {
152-
unsafe { (*self.current_task.borrow().stack).bottom() }
172+
irqsave(|| unsafe { (*self.current_task.borrow().stack).bottom() })
153173
}
154174

155175
pub fn get_root_page_table(&self) -> usize {
@@ -237,8 +257,6 @@ impl Scheduler {
237257
}
238258

239259
pub fn reschedule(&mut self) {
240-
let flags = irq_nested_disable();
241-
self.schedule();
242-
irq_nested_enable(flags);
260+
irqsave(|| self.schedule());
243261
}
244262
}

0 commit comments

Comments
 (0)