diff options
| author | Brian Anderson <banderson@mozilla.com> | 2013-03-12 00:48:41 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2013-03-18 16:59:10 -0700 |
| commit | e8ddef93da5f112795eff66ff7dc7ccccc1baa86 (patch) | |
| tree | 223fad2fcc8d4e8b654925003cc596409136d69f /src/libcore | |
| parent | 087a015a727b11d46ff5a309ff37c7967e8636d1 (diff) | |
| download | rust-e8ddef93da5f112795eff66ff7dc7ccccc1baa86.tar.gz rust-e8ddef93da5f112795eff66ff7dc7ccccc1baa86.zip | |
core: Cleanup rt::context
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/rt/context.rs | 41 | ||||
| -rw-r--r-- | src/libcore/rt/sched.rs | 10 | ||||
| -rw-r--r-- | src/libcore/rt/stack.rs | 1 |
3 files changed, 35 insertions, 17 deletions
diff --git a/src/libcore/rt/context.rs b/src/libcore/rt/context.rs index dfb7bdf04c3..11512c3fe7a 100644 --- a/src/libcore/rt/context.rs +++ b/src/libcore/rt/context.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use option::*; use super::stack::StackSegment; use libc::c_void; use cast::{transmute, transmute_mut_unsafe, @@ -16,17 +17,30 @@ use cast::{transmute, transmute_mut_unsafe, // XXX: Registers is boxed so that it is 16-byte aligned, for storing // SSE regs. It would be marginally better not to do this. In C++ we // use an attribute on a struct. -pub struct Context(~Registers); +// XXX: It would be nice to define regs as `~Option<Registers>` since +// the registers are sometimes empty, but the discriminant would +// then misalign the regs again. +pub struct Context { + /// The context entry point, saved here for later destruction + start: Option<~~fn()>, + /// Hold the registers while the task or scheduler is suspended + regs: ~Registers +} pub impl Context { static fn empty() -> Context { - Context(new_regs()) + Context { + start: None, + regs: new_regs() + } } /// Create a new context that will resume execution by running ~fn() - /// # Safety Note - /// The `start` closure must remain valid for the life of the Task - static fn new(start: &~fn(), stack: &mut StackSegment) -> Context { + static fn new(start: ~fn(), stack: &mut StackSegment) -> Context { + // XXX: Putting main into a ~ so it's a thin pointer and can + // be passed to the spawn function. Another unfortunate + // allocation + let start = ~start; // The C-ABI function that is the task entry point extern fn task_start_wrapper(f: &~fn()) { (*f)() } @@ -46,15 +60,24 @@ pub impl Context { initialize_call_frame(&mut *regs, fp, argp, sp); - return Context(regs); + return Context { + start: Some(start), + regs: regs + } } + /* Switch contexts + + Suspend the current execution context and resume another by + saving the registers values of the executing thread to a Context + then loading the registers from a previously saved Context. + */ static fn swap(out_context: &mut Context, in_context: &Context) { let out_regs: &mut Registers = match out_context { - &Context(~ref mut r) => r + &Context { regs: ~ref mut r, _ } => r }; let in_regs: &Registers = match in_context { - &Context(~ref r) => r + &Context { regs: ~ref r, _ } => r }; unsafe { swap_registers(out_regs, in_regs) }; @@ -88,7 +111,7 @@ fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) { let sp = align_down(sp); - let sp = mut_offset(sp, -4); // XXX: -4 words? Needs this be done at all? + let sp = mut_offset(sp, -4); unsafe { *sp = arg as uint; } let sp = mut_offset(sp, -1); diff --git a/src/libcore/rt/sched.rs b/src/libcore/rt/sched.rs index 8f315452e5e..ff0b3d28e8d 100644 --- a/src/libcore/rt/sched.rs +++ b/src/libcore/rt/sched.rs @@ -285,8 +285,6 @@ pub impl Scheduler { const TASK_MIN_STACK_SIZE: uint = 10000000; // XXX: Too much stack pub struct Task { - /// The task entry point, saved here for later destruction - priv start: ~~fn(), /// The segment of stack on which the task is currently running or, /// if the task is blocked, on which the task will resume execution priv current_stack_segment: StackSegment, @@ -297,15 +295,11 @@ pub struct Task { impl Task { static fn new(stack_pool: &mut StackPool, start: ~fn()) -> Task { - // XXX: Putting main into a ~ so it's a thin pointer and can - // be passed to the spawn function. Another unfortunate - // allocation - let start = ~Task::build_start_wrapper(start); + let start = Task::build_start_wrapper(start); let mut stack = stack_pool.take_segment(TASK_MIN_STACK_SIZE); // NB: Context holds a pointer to that ~fn - let initial_context = Context::new(&*start, &mut stack); + let initial_context = Context::new(start, &mut stack); return Task { - start: start, current_stack_segment: stack, saved_context: initial_context, }; diff --git a/src/libcore/rt/stack.rs b/src/libcore/rt/stack.rs index 02c47218ed8..ef48025ffe6 100644 --- a/src/libcore/rt/stack.rs +++ b/src/libcore/rt/stack.rs @@ -27,6 +27,7 @@ pub impl StackSegment { } } + /// Point one word beyond the high end of the allocated stack fn end(&self) -> *uint { unsafe { vec::raw::to_ptr(self.buf).offset(self.buf.len()) as *uint |
