Skip to content

Commit b9302f9

Browse files
committed
---
yaml --- r: 143014 b: refs/heads/try2 c: 87bbcb5 h: refs/heads/master v: v3
1 parent a195832 commit b9302f9

File tree

2 files changed

+21
-62
lines changed

2 files changed

+21
-62
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: 9bbec651dfff68c93d7213fceadecc21c324b0cb
8+
refs/heads/try2: 87bbcb579a170f4d2c36df4370703075c81b0b5d
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/libstd/task/spawn.rs

Lines changed: 20 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,8 @@ struct AncestorNode {
178178
// approach the tail of the list.
179179
// FIXME(#3068): Make the generation counter togglable with #[cfg(debug)].
180180
generation: uint,
181-
// Should really be a non-option. This way appeases borrowck.
182-
parent_group: Option<TaskGroupArc>,
181+
// Handle to the tasks in the group of the current generation.
182+
parent_group: TaskGroupArc,
183183
// Recursive rest of the list.
184184
ancestors: AncestorList,
185185
}
@@ -221,18 +221,13 @@ fn each_ancestor(list: &mut AncestorList,
221221
bail_blk: &fn(TaskGroupInner),
222222
forward_blk: &fn(TaskGroupInner) -> bool,
223223
last_generation: uint) -> bool {
224-
// Need to swap the list out to use it, to appease borrowck.
225-
let tmp_list = util::replace(&mut *list, AncestorList(None));
226224
let (coalesce_this, early_break) =
227-
iterate(&tmp_list, bail_blk, forward_blk, last_generation);
225+
iterate(list, bail_blk, forward_blk, last_generation);
228226
// What should our next ancestor end up being?
229227
if coalesce_this.is_some() {
230228
// Needed coalesce. Our next ancestor becomes our old
231229
// ancestor's next ancestor. ("next = old_next->next;")
232230
*list = coalesce_this.unwrap();
233-
} else {
234-
// No coalesce; restore from tmp. ("next = old_next;")
235-
*list = tmp_list;
236231
}
237232
return early_break;
238233
}
@@ -245,7 +240,7 @@ fn each_ancestor(list: &mut AncestorList,
245240
// bool:
246241
// True if the supplied block did 'break', here or in any recursive
247242
// calls. If so, must call the unwinder on all previous nodes.
248-
fn iterate(ancestors: &AncestorList,
243+
fn iterate(ancestors: &mut AncestorList,
249244
bail_blk: &fn(TaskGroupInner),
250245
forward_blk: &fn(TaskGroupInner) -> bool,
251246
last_generation: uint)
@@ -263,7 +258,7 @@ fn each_ancestor(list: &mut AncestorList,
263258

264259
// The map defaults to None, because if ancestors is None, we're at
265260
// the end of the list, which doesn't make sense to coalesce.
266-
return do (**ancestors).map_default((None,false)) |ancestor_arc| {
261+
do ancestors.map_default((None,false)) |ancestor_arc| {
267262
// NB: Takes a lock! (this ancestor node)
268263
do access_ancestors(ancestor_arc) |nobe| {
269264
// Argh, but we couldn't give it to coalesce() otherwise.
@@ -276,7 +271,7 @@ fn each_ancestor(list: &mut AncestorList,
276271
let mut nobe_is_dead = false;
277272
let do_continue =
278273
// NB: Takes a lock! (this ancestor node's parent group)
279-
do with_parent_tg(&mut nobe.parent_group) |tg_opt| {
274+
do access_group(&nobe.parent_group) |tg_opt| {
280275
// Decide whether this group is dead. Note that the
281276
// group being *dead* is disjoint from it *failing*.
282277
nobe_is_dead = match *tg_opt {
@@ -305,7 +300,7 @@ fn each_ancestor(list: &mut AncestorList,
305300
* Step 3: Maybe unwind; compute return info for our caller.
306301
*##########################################################*/
307302
if need_unwind && !nobe_is_dead {
308-
do with_parent_tg(&mut nobe.parent_group) |tg_opt| {
303+
do access_group(&nobe.parent_group) |tg_opt| {
309304
bail_blk(tg_opt)
310305
}
311306
}
@@ -321,16 +316,6 @@ fn each_ancestor(list: &mut AncestorList,
321316
(None, need_unwind)
322317
}
323318
}
324-
};
325-
326-
// Wrapper around exclusive::with that appeases borrowck.
327-
fn with_parent_tg<U>(parent_group: &mut Option<TaskGroupArc>,
328-
blk: &fn(TaskGroupInner) -> U) -> U {
329-
// If this trips, more likely the problem is 'blk' failed inside.
330-
let tmp_arc = parent_group.take_unwrap();
331-
let result = do access_group(&tmp_arc) |tg_opt| { blk(tg_opt) };
332-
*parent_group = Some(tmp_arc);
333-
result
334319
}
335320
}
336321
}
@@ -544,7 +529,7 @@ impl RuntimeGlue {
544529
}
545530
}
546531

547-
fn with_my_taskgroup<U>(blk: &fn(&mut TCB) -> U) -> U {
532+
fn with_my_taskgroup<U>(blk: &fn(&TCB) -> U) -> U {
548533
match context() {
549534
OldTaskContext => unsafe {
550535
let me = rt::rust_get_task();
@@ -561,9 +546,9 @@ impl RuntimeGlue {
561546
// Main task/group has no ancestors, no notifier, etc.
562547
let group = @@mut TCB(tasks, AncestorList(None), true, None);
563548
local_set(OldHandle(me), taskgroup_key(), group);
564-
blk(&mut **group)
549+
blk(&**group)
565550
}
566-
Some(&group) => blk(&mut **group)
551+
Some(&group) => blk(&**group)
567552
}
568553
}
569554
},
@@ -583,9 +568,9 @@ impl RuntimeGlue {
583568
}));
584569
let group = TCB(tasks, AncestorList(None), true, None);
585570
(*me).taskgroup = Some(group);
586-
(*me).taskgroup.get_mut_ref()
571+
(*me).taskgroup.get_ref()
587572
}
588-
Some(ref mut group) => group,
573+
Some(ref group) => group,
589574
})
590575
},
591576
SchedulerContext | GlobalContext => rtabort!("spawning in bad context"),
@@ -595,64 +580,44 @@ impl RuntimeGlue {
595580

596581
fn gen_child_taskgroup(linked: bool, supervised: bool)
597582
-> (TaskGroupArc, AncestorList, bool) {
598-
return do RuntimeGlue::with_my_taskgroup |spawner_group| {
583+
do RuntimeGlue::with_my_taskgroup |spawner_group| {
584+
let ancestors = AncestorList(spawner_group.ancestors.map(|x| x.clone()));
599585
if linked {
600586
// Child is in the same group as spawner.
601-
let g = spawner_group.tasks.clone();
602587
// Child's ancestors are spawner's ancestors.
603-
let a = share_ancestors(&mut spawner_group.ancestors);
604588
// Propagate main-ness.
605-
(g, a, spawner_group.is_main)
589+
(spawner_group.tasks.clone(), ancestors, spawner_group.is_main)
606590
} else {
607591
// Child is in a separate group from spawner.
608592
let g = exclusive(Some(TaskGroupData {
609593
members: new_taskset(),
610594
descendants: new_taskset(),
611595
}));
612596
let a = if supervised {
613-
// Child's ancestors start with the spawner.
614-
let old_ancestors =
615-
share_ancestors(&mut spawner_group.ancestors);
616597
// FIXME(#3068) - The generation counter is only used for a
617598
// debug assertion, but initialising it requires locking a
618599
// mutex. Hence it should be enabled only in debug builds.
619600
let new_generation =
620-
match *old_ancestors {
601+
match *ancestors {
621602
Some(ref arc) => {
622603
access_ancestors(arc, |a| a.generation+1)
623604
}
624605
None => 0 // the actual value doesn't really matter.
625606
};
626607
assert!(new_generation < uint::max_value);
608+
// Child's ancestors start with the spawner.
627609
// Build a new node in the ancestor list.
628610
AncestorList(Some(exclusive(AncestorNode {
629611
generation: new_generation,
630-
parent_group: Some(spawner_group.tasks.clone()),
631-
ancestors: old_ancestors,
612+
parent_group: spawner_group.tasks.clone(),
613+
ancestors: ancestors,
632614
})))
633615
} else {
634616
// Child has no ancestors.
635617
AncestorList(None)
636618
};
637619
(g, a, false)
638620
}
639-
};
640-
641-
fn share_ancestors(ancestors: &mut AncestorList) -> AncestorList {
642-
// Appease the borrow-checker. Really this wants to be written as:
643-
// match ancestors
644-
// Some(ancestor_arc) { ancestor_list(Some(ancestor_arc.clone())) }
645-
// None { ancestor_list(None) }
646-
let tmp = util::replace(&mut **ancestors, None);
647-
if tmp.is_some() {
648-
let ancestor_arc = tmp.unwrap();
649-
let result = ancestor_arc.clone();
650-
error!("cloned ancestors");
651-
**ancestors = Some(ancestor_arc);
652-
AncestorList(Some(result))
653-
} else {
654-
AncestorList(None)
655-
}
656621
}
657622
}
658623

@@ -754,14 +719,8 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) {
754719
};
755720
assert!(!new_task.is_null());
756721
// Getting killed after here would leak the task.
757-
let notify_chan = if opts.notify_chan.is_none() {
758-
None
759-
} else {
760-
Some(opts.notify_chan.take_unwrap())
761-
};
762-
763722
let child_wrapper = make_child_wrapper(new_task, child_tg,
764-
ancestors, is_main, notify_chan, f);
723+
ancestors, is_main, opts.notify_chan.take(), f);
765724

766725
let closure = cast::transmute(&child_wrapper);
767726

0 commit comments

Comments
 (0)