Skip to content

Commit e8ddef9

Browse files
committed
core: Cleanup rt::context
1 parent 087a015 commit e8ddef9

File tree

3 files changed

+35
-17
lines changed

3 files changed

+35
-17
lines changed

src/libcore/rt/context.rs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use option::*;
1112
use super::stack::StackSegment;
1213
use libc::c_void;
1314
use cast::{transmute, transmute_mut_unsafe,
@@ -16,17 +17,30 @@ use cast::{transmute, transmute_mut_unsafe,
1617
// XXX: Registers is boxed so that it is 16-byte aligned, for storing
1718
// SSE regs. It would be marginally better not to do this. In C++ we
1819
// use an attribute on a struct.
19-
pub struct Context(~Registers);
20+
// XXX: It would be nice to define regs as `~Option<Registers>` since
21+
// the registers are sometimes empty, but the discriminant would
22+
// then misalign the regs again.
23+
pub struct Context {
24+
/// The context entry point, saved here for later destruction
25+
start: Option<~~fn()>,
26+
/// Hold the registers while the task or scheduler is suspended
27+
regs: ~Registers
28+
}
2029

2130
pub impl Context {
2231
static fn empty() -> Context {
23-
Context(new_regs())
32+
Context {
33+
start: None,
34+
regs: new_regs()
35+
}
2436
}
2537

2638
/// Create a new context that will resume execution by running ~fn()
27-
/// # Safety Note
28-
/// The `start` closure must remain valid for the life of the Task
29-
static fn new(start: &~fn(), stack: &mut StackSegment) -> Context {
39+
static fn new(start: ~fn(), stack: &mut StackSegment) -> Context {
40+
// XXX: Putting main into a ~ so it's a thin pointer and can
41+
// be passed to the spawn function. Another unfortunate
42+
// allocation
43+
let start = ~start;
3044

3145
// The C-ABI function that is the task entry point
3246
extern fn task_start_wrapper(f: &~fn()) { (*f)() }
@@ -46,15 +60,24 @@ pub impl Context {
4660

4761
initialize_call_frame(&mut *regs, fp, argp, sp);
4862

49-
return Context(regs);
63+
return Context {
64+
start: Some(start),
65+
regs: regs
66+
}
5067
}
5168

69+
/* Switch contexts
70+
71+
Suspend the current execution context and resume another by
72+
saving the registers values of the executing thread to a Context
73+
then loading the registers from a previously saved Context.
74+
*/
5275
static fn swap(out_context: &mut Context, in_context: &Context) {
5376
let out_regs: &mut Registers = match out_context {
54-
&Context(~ref mut r) => r
77+
&Context { regs: ~ref mut r, _ } => r
5578
};
5679
let in_regs: &Registers = match in_context {
57-
&Context(~ref r) => r
80+
&Context { regs: ~ref r, _ } => r
5881
};
5982

6083
unsafe { swap_registers(out_regs, in_regs) };
@@ -88,7 +111,7 @@ fn initialize_call_frame(regs: &mut Registers,
88111
fptr: *c_void, arg: *c_void, sp: *mut uint) {
89112

90113
let sp = align_down(sp);
91-
let sp = mut_offset(sp, -4); // XXX: -4 words? Needs this be done at all?
114+
let sp = mut_offset(sp, -4);
92115

93116
unsafe { *sp = arg as uint; }
94117
let sp = mut_offset(sp, -1);

src/libcore/rt/sched.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,6 @@ pub impl Scheduler {
285285
const TASK_MIN_STACK_SIZE: uint = 10000000; // XXX: Too much stack
286286

287287
pub struct Task {
288-
/// The task entry point, saved here for later destruction
289-
priv start: ~~fn(),
290288
/// The segment of stack on which the task is currently running or,
291289
/// if the task is blocked, on which the task will resume execution
292290
priv current_stack_segment: StackSegment,
@@ -297,15 +295,11 @@ pub struct Task {
297295

298296
impl Task {
299297
static fn new(stack_pool: &mut StackPool, start: ~fn()) -> Task {
300-
// XXX: Putting main into a ~ so it's a thin pointer and can
301-
// be passed to the spawn function. Another unfortunate
302-
// allocation
303-
let start = ~Task::build_start_wrapper(start);
298+
let start = Task::build_start_wrapper(start);
304299
let mut stack = stack_pool.take_segment(TASK_MIN_STACK_SIZE);
305300
// NB: Context holds a pointer to that ~fn
306-
let initial_context = Context::new(&*start, &mut stack);
301+
let initial_context = Context::new(start, &mut stack);
307302
return Task {
308-
start: start,
309303
current_stack_segment: stack,
310304
saved_context: initial_context,
311305
};

src/libcore/rt/stack.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub impl StackSegment {
2727
}
2828
}
2929

30+
/// Point one word beyond the high end of the allocated stack
3031
fn end(&self) -> *uint {
3132
unsafe {
3233
vec::raw::to_ptr(self.buf).offset(self.buf.len()) as *uint

0 commit comments

Comments
 (0)