Skip to content

Commit 4224fc7

Browse files
committed
added functionality to tell schedulers to refuse to run tasks that are not pinned to them
1 parent 8428081 commit 4224fc7

File tree

2 files changed

+60
-18
lines changed

2 files changed

+60
-18
lines changed

src/libstd/rt/sched.rs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ pub struct Scheduler {
7070
/// An action performed after a context switch on behalf of the
7171
/// code running before the context switch
7272
priv cleanup_job: Option<CleanupJob>,
73-
metrics: SchedMetrics
73+
metrics: SchedMetrics,
74+
/// Should this scheduler run any task, or only pinned tasks?
75+
run_anything: bool
7476
}
7577

7678
pub struct SchedHandle {
@@ -136,6 +138,16 @@ pub impl Scheduler {
136138
sleeper_list: SleeperList)
137139
-> Scheduler {
138140

141+
Scheduler::new_special(event_loop, work_queue, sleeper_list, true)
142+
143+
}
144+
145+
fn new_special(event_loop: ~EventLoopObject,
146+
work_queue: WorkQueue<~Coroutine>,
147+
sleeper_list: SleeperList,
148+
run_anything: bool)
149+
-> Scheduler {
150+
139151
// Lazily initialize the runtime TLS key
140152
local_ptr::init_tls_key();
141153

@@ -150,7 +162,8 @@ pub impl Scheduler {
150162
saved_context: Context::empty(),
151163
current_task: None,
152164
cleanup_job: None,
153-
metrics: SchedMetrics::new()
165+
metrics: SchedMetrics::new(),
166+
run_anything: run_anything
154167
}
155168
}
156169

@@ -429,19 +442,28 @@ pub impl Scheduler {
429442
assert!(!self.in_task_context());
430443

431444
rtdebug!("looking in work queue for task to schedule");
432-
433445
let mut this = self;
434-
match this.work_queue.pop() {
435-
Some(task) => {
436-
rtdebug!("resuming task from work queue");
437-
this.resume_task_immediately(task);
438-
return true;
439-
}
440-
None => {
441-
rtdebug!("no tasks in queue");
442-
Local::put(this);
443-
return false;
446+
447+
if this.run_anything {
448+
match this.work_queue.pop() {
449+
Some(task) => {
450+
rtdebug!("resuming task from work queue");
451+
this.resume_task_immediately(task);
452+
return true;
453+
}
454+
None => {
455+
rtdebug!("no tasks in queue");
456+
Local::put(this);
457+
return false;
458+
}
444459
}
460+
} else {
461+
// In this branch we have a scheduler that is not allowed
462+
// to run unpinned tasks. As such it will only get tasks
463+
// to run from the message queue.
464+
rtdebug!("skipping resume_task_from_queue");
465+
Local::put(this);
466+
return false;
445467
}
446468
}
447469

src/libstd/rt/test.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,23 +157,43 @@ pub fn run_in_mt_newsched_task_random_homed() {
157157
let mut handles = ~[];
158158
let mut scheds = ~[];
159159

160-
for uint::range(0, nthreads) |_| {
160+
// create a few special schedulers, those with even indicies
161+
// will be pinned-only
162+
for uint::range(0, nthreads) |i| {
163+
let special = (i % 2) == 0;
161164
let loop_ = ~UvEventLoop::new();
162-
let mut sched = ~Scheduler::new(loop_, work_queue.clone(), sleepers.clone());
165+
let mut sched = ~Scheduler::new_special(loop_, work_queue.clone(), sleepers.clone(), special);
163166
let handle = sched.make_handle();
164167
handles.push(handle);
165168
scheds.push(sched);
166-
}
169+
}
167170

168171
// Schedule a pile o tasks
169-
let n = 120*stress_factor();
172+
let n = 5*stress_factor();
170173
for uint::range(0,n) |_i| {
171174
rtdebug!("creating task: %u", _i);
172175
let hf: ~fn() = || { assert!(true) };
173176
spawntask_homed(&mut scheds, hf);
174177
}
175178

176-
let f: ~fn() = || { assert!(true); };
179+
// Now we want another pile o tasks that do not ever run on a
180+
// special scheduler, because they are normal tasks. Because
181+
// we can we put these in the "main" task.
182+
183+
let n = 5*stress_factor();
184+
185+
let f: ~fn() = || {
186+
for uint::range(0,n) |_| {
187+
let f: ~fn() = || {
188+
// Borrow the scheduler we run on and check if it is
189+
// privliged.
190+
do Local::borrow::<Scheduler,()> |sched| {
191+
assert!(sched.run_anything);
192+
};
193+
};
194+
spawntask_random(f);
195+
};
196+
};
177197

178198
let f_cell = Cell(f);
179199
let handles = Cell(handles);

0 commit comments

Comments
 (0)