Skip to content

Commit b20b105

Browse files
committed
---
yaml --- r: 96936 b: refs/heads/dist-snap c: 9f00586 h: refs/heads/master v: v3
1 parent 5447ae7 commit b20b105

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: c274a6888410ce3e357e014568b43310ed787d36
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
9-
refs/heads/dist-snap: f25c81a51a752786ce8936b503c16912478a89fd
9+
refs/heads/dist-snap: 9f005866e59246bbe2721fc5a6c993c5ae7e1431
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1212
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/src/libgreen/context.rs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use stack::StackSegment;
2424
// then misalign the regs again.
2525
pub struct Context {
2626
/// The context entry point, saved here for later destruction
27-
priv start: ~Option<proc()>,
27+
priv start: Option<~proc()>,
2828
/// Hold the registers while the task or scheduler is suspended
2929
priv regs: ~Registers,
3030
/// Lower bound and upper bound for the stack
@@ -34,7 +34,7 @@ pub struct Context {
3434
impl Context {
3535
pub fn empty() -> Context {
3636
Context {
37-
start: ~None,
37+
start: None,
3838
regs: new_regs(),
3939
stack_bounds: None,
4040
}
@@ -43,8 +43,26 @@ impl Context {
4343
/// Create a new context that will resume execution by running proc()
4444
pub fn new(start: proc(), stack: &mut StackSegment) -> Context {
4545
// The C-ABI function that is the task entry point
46-
extern fn task_start_wrapper(f: &mut Option<proc()>) {
47-
f.take_unwrap()()
46+
//
47+
// Note that this function is a little sketchy. We're taking a
48+
// procedure, transmuting it to a stack-closure, and then calling to
49+
// closure. This leverages the fact that the representation of these two
50+
// types is the same.
51+
//
52+
// The reason that we're doing this is that this procedure is expected
53+
// to never return. The codegen which frees the environment of the
54+
// procedure occurs *after* the procedure has completed, and this means
55+
// that we'll never actually free the procedure.
56+
//
57+
// To solve this, we use this transmute (to not trigger the procedure
58+
// deallocation here), and then store a copy of the procedure in the
59+
// `Context` structure returned. When the `Context` is deallocated, then
60+
// the entire procedure box will be deallocated as well.
61+
extern fn task_start_wrapper(f: &proc()) {
62+
unsafe {
63+
let f: &|| = transmute(f);
64+
(*f)()
65+
}
4866
}
4967

5068
let sp: *uint = stack.end();
@@ -60,10 +78,10 @@ impl Context {
6078
// FIXME #7767: Putting main into a ~ so it's a thin pointer and can
6179
// be passed to the spawn function. Another unfortunate
6280
// allocation
63-
let box = ~Some(start);
81+
let start = ~start;
6482
initialize_call_frame(&mut *regs,
6583
task_start_wrapper as *c_void,
66-
unsafe { transmute(&*box) },
84+
unsafe { transmute(&*start) },
6785
sp);
6886

6987
// Scheduler tasks don't have a stack in the "we allocated it" sense,
@@ -78,7 +96,7 @@ impl Context {
7896
Some((stack_base as uint, sp as uint))
7997
};
8098
return Context {
81-
start: box,
99+
start: Some(start),
82100
regs: regs,
83101
stack_bounds: bounds,
84102
}

0 commit comments

Comments
 (0)