Skip to content

Commit 5f52aec

Browse files
committed
core::rt: Schedulers only need a single cleanup_job at a time
Each context switch has up to one cleanup job and it is always executed immediately after the context switch.
1 parent 6b084ba commit 5f52aec

File tree

1 file changed

+31
-31
lines changed

1 file changed

+31
-31
lines changed

src/libcore/rt/sched.rs

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,9 @@ pub struct Scheduler {
3838
priv saved_context: Context,
3939
/// The currently executing task
4040
priv current_task: Option<~Task>,
41-
/// A queue of jobs to perform immediately upon return from task
42-
/// context to scheduler context.
43-
/// XXX: This probably should be a single cleanup action and it
44-
/// should run after a context switch, not on return from the
45-
/// scheduler
46-
priv cleanup_jobs: ~[CleanupJob]
41+
/// An action performed after a context switch on behalf of the
42+
/// code running before the context switch
43+
priv cleanup_job: Option<CleanupJob>
4744
}
4845

4946
// XXX: Some hacks to put a &fn in Scheduler without borrowck
@@ -84,7 +81,7 @@ pub impl Scheduler {
8481
stack_pool: StackPool::new(),
8582
saved_context: Context::empty(),
8683
current_task: None,
87-
cleanup_jobs: ~[]
84+
cleanup_job: None
8885
}
8986
}
9087

@@ -165,7 +162,7 @@ pub impl Scheduler {
165162
assert!(self.current_task.is_none());
166163

167164
// Running tasks may have asked us to do some cleanup
168-
self.run_cleanup_jobs();
165+
self.run_cleanup_job();
169166
}
170167

171168

@@ -212,7 +209,7 @@ pub impl Scheduler {
212209
Context::swap(last_task_context, sched_context);
213210
}
214211

215-
self.run_cleanup_jobs();
212+
self.run_cleanup_job();
216213
}
217214

218215
/// Switch directly to another task, without going through the scheduler.
@@ -233,29 +230,33 @@ pub impl Scheduler {
233230
Context::swap(last_task_context, next_task_context);
234231
}
235232

236-
self.run_cleanup_jobs();
233+
self.run_cleanup_job();
237234
}
238235

239236
// * Other stuff
240237

241238
fn in_task_context(&self) -> bool { self.current_task.is_some() }
242239

243240
fn enqueue_cleanup_job(&mut self, job: CleanupJob) {
244-
self.cleanup_jobs.unshift(job);
241+
assert!(self.cleanup_job.is_none());
242+
self.cleanup_job = Some(job);
245243
}
246244

247-
fn run_cleanup_jobs(&mut self) {
245+
fn run_cleanup_job(&mut self) {
248246
rtdebug!("running cleanup jobs");
249247

250-
while !self.cleanup_jobs.is_empty() {
251-
match self.cleanup_jobs.pop() {
252-
RescheduleTask(task) => {
253-
// NB: Pushing to the *front* of the queue
254-
self.task_queue.push_front(task);
255-
}
256-
RecycleTask(task) => task.recycle(&mut self.stack_pool),
257-
GiveTask(task, f) => (f.to_fn())(self, task)
248+
if self.cleanup_job.is_none() {
249+
return;
250+
}
251+
252+
let cleanup_job = self.cleanup_job.swap_unwrap();
253+
match cleanup_job {
254+
RescheduleTask(task) => {
255+
// NB: Pushing to the *front* of the queue
256+
self.task_queue.push_front(task);
258257
}
258+
RecycleTask(task) => task.recycle(&mut self.stack_pool),
259+
GiveTask(task, f) => (f.to_fn())(self, task)
259260
}
260261
}
261262

@@ -271,16 +272,15 @@ pub impl Scheduler {
271272
fn get_contexts(&mut self) -> (&'self mut Context,
272273
Option<&'self mut Context>,
273274
Option<&'self mut Context>) {
274-
let last_task = if !self.cleanup_jobs.is_empty() {
275-
let last_job: &'self mut CleanupJob = &mut self.cleanup_jobs[0];
276-
let last_task: &'self Task = match last_job {
277-
&RescheduleTask(~ref task) => task,
278-
&RecycleTask(~ref task) => task,
279-
&GiveTask(~ref task, _) => task,
280-
};
281-
Some(last_task)
282-
} else {
283-
None
275+
let last_task = match self.cleanup_job {
276+
Some(RescheduleTask(~ref task)) |
277+
Some(RecycleTask(~ref task)) |
278+
Some(GiveTask(~ref task, _)) => {
279+
Some(task)
280+
}
281+
None => {
282+
None
283+
}
284284
};
285285
// XXX: Pattern matching mutable pointers above doesn't work
286286
// because borrowck thinks the three patterns are conflicting
@@ -329,7 +329,7 @@ pub impl Task {
329329
// have asked us to do some cleanup.
330330
let mut sched = ThreadLocalScheduler::new();
331331
let sched = sched.get_scheduler();
332-
sched.run_cleanup_jobs();
332+
sched.run_cleanup_job();
333333

334334
start();
335335

0 commit comments

Comments
 (0)