Skip to content

Commit a5f55b3

Browse files
committed
minor tweaks - unboxed the coroutine so that it is no longer a ~ pointer inside the task struct, and also added an assert to verify that send is never called inside scheduler context as it is undefined (BROKEN) if that happens
1 parent 997719c commit a5f55b3

File tree

8 files changed

+72
-32
lines changed

8 files changed

+72
-32
lines changed

src/libstd/rt/comm.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use util::Void;
2424
use comm::{GenericChan, GenericSmartChan, GenericPort, Peekable};
2525
use cell::Cell;
2626
use clone::Clone;
27+
use rt::{context, SchedulerContext};
2728

2829
/// A combined refcount / BlockedTask-as-uint pointer.
2930
///
@@ -90,6 +91,9 @@ impl<T> ChanOne<T> {
9091
}
9192

9293
pub fn try_send(self, val: T) -> bool {
94+
95+
rtassert!(context() != SchedulerContext);
96+
9397
let mut this = self;
9498
let mut recvr_active = true;
9599
let packet = this.packet();

src/libstd/rt/io/net/tcp.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ mod test {
571571
#[cfg(test)]
572572
fn socket_name(addr: IpAddr) {
573573
do run_in_newsched_task {
574-
do spawntask_immediately {
574+
do spawntask {
575575
let listener = TcpListener::bind(addr);
576576

577577
assert!(listener.is_some());
@@ -590,13 +590,13 @@ mod test {
590590
#[cfg(test)]
591591
fn peer_name(addr: IpAddr) {
592592
do run_in_newsched_task {
593-
do spawntask_immediately {
593+
do spawntask {
594594
let mut listener = TcpListener::bind(addr);
595595

596596
listener.accept();
597597
}
598598

599-
do spawntask_immediately {
599+
do spawntask {
600600
let stream = TcpStream::connect(addr);
601601

602602
assert!(stream.is_some());

src/libstd/rt/io/net/udp.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ mod test {
267267
#[cfg(test)]
268268
fn socket_name(addr: IpAddr) {
269269
do run_in_newsched_task {
270-
do spawntask_immediately {
270+
do spawntask {
271271
let server = UdpSocket::bind(addr);
272272

273273
assert!(server.is_some());

src/libstd/rt/local.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,7 @@ impl Local for IoFactoryObject {
120120

121121
#[cfg(test)]
122122
mod test {
123-
// use unstable::run_in_bare_thread;
124123
use rt::test::*;
125-
// use rt::sched::Scheduler;
126124
use super::*;
127125
use rt::task::Task;
128126
use rt::local_ptr;

src/libstd/rt/mod.rs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ use ptr::RawPtr;
7070
use rt::local::Local;
7171
use rt::sched::{Scheduler, Shutdown};
7272
use rt::sleeper_list::SleeperList;
73-
use rt::task::{Task, SchedTask, GreenTask};
73+
use rt::task::{Task, SchedTask, GreenTask, Sched};
7474
use rt::thread::Thread;
7575
use rt::work_queue::WorkQueue;
7676
use rt::uv::uvio::UvEventLoop;
@@ -244,6 +244,8 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
244244

245245
let nscheds = util::default_sched_threads();
246246

247+
let main = Cell::new(main);
248+
247249
// The shared list of sleeping schedulers. Schedulers wake each other
248250
// occassionally to do new work.
249251
let sleepers = SleeperList::new();
@@ -268,12 +270,19 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
268270

269271
// If we need a main-thread task then create a main thread scheduler
270272
// that will reject any task that isn't pinned to it
271-
let mut main_sched = if use_main_sched {
273+
let main_sched = if use_main_sched {
274+
275+
// Create a friend handle.
276+
let mut friend_sched = scheds.pop();
277+
let friend_handle = friend_sched.make_handle();
278+
scheds.push(friend_sched);
279+
272280
let main_loop = ~UvEventLoop::new();
273281
let mut main_sched = ~Scheduler::new_special(main_loop,
274282
work_queue.clone(),
275283
sleepers.clone(),
276-
false);
284+
false,
285+
Some(friend_handle));
277286
let main_handle = main_sched.make_handle();
278287
handles.push(main_handle);
279288
Some(main_sched)
@@ -312,15 +321,16 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
312321

313322
let mut threads = ~[];
314323

324+
let on_exit = Cell::new(on_exit);
325+
315326
if !use_main_sched {
316327

317328
// In the case where we do not use a main_thread scheduler we
318329
// run the main task in one of our threads.
319-
320-
let main_cell = Cell::new(main);
330+
321331
let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool,
322-
main_cell.take());
323-
main_task.death.on_exit = Some(on_exit);
332+
main.take());
333+
main_task.death.on_exit = Some(on_exit.take());
324334
let main_task_cell = Cell::new(main_task);
325335

326336
let sched = scheds.pop();
@@ -347,16 +357,18 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
347357
}
348358

349359
// If we do have a main thread scheduler, run it now.
350-
360+
351361
if use_main_sched {
362+
363+
let mut main_sched = main_sched.get();
364+
352365
let home = Sched(main_sched.make_handle());
353-
let mut main_task = ~Task::new_root_homed(&mut scheds[0].stack_pool,
354-
home, main);
355-
main_task.death.on_exit = Some(on_exit);
356-
let main_task_cell = Cell::new(main_task);
357-
sched.bootstrap(main_task);
366+
let mut main_task = ~Task::new_root_homed(&mut scheds[0].stack_pool,
367+
home, main.take());
368+
main_task.death.on_exit = Some(on_exit.take());
369+
main_sched.bootstrap(main_task);
358370
}
359-
371+
360372
// Wait for schedulers
361373
foreach thread in threads.consume_iter() {
362374
thread.join();

src/libstd/rt/sched.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
use either::{Left, Right};
1212
use option::{Option, Some, None};
13-
use sys;
1413
use cast::{transmute, transmute_mut_region, transmute_mut_unsafe};
1514
use clone::Clone;
1615
use unstable::raw;
@@ -334,7 +333,7 @@ impl Scheduler {
334333
return None;
335334
}
336335
Some(TaskFromFriend(task)) => {
337-
this.resume_task_immediately(task);
336+
this.schedule_task_sched_context(task);
338337
return None;
339338
}
340339
Some(Wake) => {
@@ -432,7 +431,6 @@ impl Scheduler {
432431
}
433432
AnySched => {
434433
task.give_home(AnySched);
435-
// this.enqueue_task(task);
436434
this.send_to_friend(task);
437435
return Some(this);
438436
}
@@ -491,6 +489,36 @@ impl Scheduler {
491489
}
492490
}
493491

492+
// BAD BAD BAD BAD BAD
493+
// Do something instead of just copy-pasting this.
494+
pub fn schedule_task_sched_context(~self, task: ~Task) -> Option<~Scheduler> {
495+
496+
// is the task home?
497+
let is_home = task.is_home_no_tls(&self);
498+
499+
// does the task have a home?
500+
let homed = task.homed();
501+
502+
let mut this = self;
503+
504+
if is_home || (!homed && this.run_anything) {
505+
// here we know we are home, execute now OR we know we
506+
// aren't homed, and that this sched doesn't care
507+
rtdebug!("task: %u is on ok sched, executing", to_uint(task));
508+
this.resume_task_immediately(task);
509+
return None;
510+
} else if !homed && !this.run_anything {
511+
// the task isn't homed, but it can't be run here
512+
this.enqueue_task(task);
513+
return Some(this);
514+
} else {
515+
// task isn't home, so don't run it here, send it home
516+
Scheduler::send_task_home(task);
517+
return Some(this);
518+
}
519+
}
520+
521+
494522
// The primary function for changing contexts. In the current
495523
// design the scheduler is just a slightly modified GreenTask, so
496524
// all context swaps are from Task to Task. The only difference

src/libstd/rt/task.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ pub struct Task {
4545
taskgroup: Option<Taskgroup>,
4646
death: Death,
4747
destroyed: bool,
48-
coroutine: Option<~Coroutine>,
4948
// FIXME(#6874/#7599) use StringRef to save on allocations
5049
name: Option<~str>,
50+
coroutine: Option<Coroutine>,
5151
sched: Option<~Scheduler>,
5252
task_type: TaskType
5353
}
@@ -128,7 +128,7 @@ impl Task {
128128
taskgroup: None,
129129
death: Death::new(),
130130
destroyed: false,
131-
coroutine: Some(~Coroutine::empty()),
131+
coroutine: Some(Coroutine::empty()),
132132
sched: None,
133133
task_type: SchedTask
134134
}
@@ -157,8 +157,8 @@ impl Task {
157157
taskgroup: None,
158158
death: Death::new(),
159159
destroyed: false,
160-
coroutine: Some(~Coroutine::new(stack_pool, start)),
161160
name: None,
161+
coroutine: Some(Coroutine::new(stack_pool, start)),
162162
sched: None,
163163
task_type: GreenTask(Some(~home))
164164
}
@@ -178,8 +178,8 @@ impl Task {
178178
// FIXME(#7544) make watching optional
179179
death: self.death.new_child(),
180180
destroyed: false,
181-
coroutine: Some(~Coroutine::new(stack_pool, start)),
182181
name: None,
182+
coroutine: Some(Coroutine::new(stack_pool, start)),
183183
sched: None,
184184
task_type: GreenTask(Some(~home))
185185
}
@@ -375,9 +375,9 @@ impl Coroutine {
375375
}
376376

377377
/// Destroy coroutine and try to reuse stack segment.
378-
pub fn recycle(~self, stack_pool: &mut StackPool) {
378+
pub fn recycle(self, stack_pool: &mut StackPool) {
379379
match self {
380-
~Coroutine { current_stack_segment, _ } => {
380+
Coroutine { current_stack_segment, _ } => {
381381
stack_pool.give_segment(current_stack_segment);
382382
}
383383
}

src/libstd/rt/uv/uvio.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -790,10 +790,8 @@ impl Drop for UvTimer {
790790
impl RtioTimer for UvTimer {
791791
fn sleep(&self, msecs: u64) {
792792
let scheduler = Local::take::<Scheduler>();
793-
assert!(scheduler.in_task_context());
794-
do scheduler.deschedule_running_task_and_then |sched, task| {
793+
do scheduler.deschedule_running_task_and_then |_sched, task| {
795794
rtdebug!("sleep: entered scheduler context");
796-
assert!(!sched.in_task_context());
797795
let task_cell = Cell::new(task);
798796
let mut watcher = **self;
799797
do watcher.start(msecs, 0) |_, status| {

0 commit comments

Comments
 (0)