forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
auto merge of rust-lang#5303 : brson/rust/newsched4, r=brson
r? Followup to rust-lang#5022. This is the same, but everything is in `core::rt` now. `std::uv_ll` is moved to `core::unstable::uvll`, with the intent that it eventually move into its own crate (blocked on rust-lang#5192 at least). I've had to disable the uv tests because of rust-lang#2064. All of `core::rt` is disabled on platforms that aren't mac or linux until I complete the windows thread local storage bindings and ARM context switching. My immediate next priorities will be to fix rust-lang#2064 and clean up the uv bindings, get everything building on all platforms.
- Loading branch information
Showing
26 changed files
with
2,789 additions
and
253 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
use super::stack::StackSegment; | ||
use libc::c_void; | ||
use cast::{transmute, transmute_mut_unsafe, | ||
transmute_region, transmute_mut_region}; | ||
|
||
// 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); | ||
|
||
pub impl Context { | ||
static fn empty() -> Context { | ||
Context(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 { | ||
|
||
// The C-ABI function that is the task entry point | ||
extern fn task_start_wrapper(f: &~fn()) { (*f)() } | ||
|
||
let fp: *c_void = task_start_wrapper as *c_void; | ||
let argp: *c_void = unsafe { transmute::<&~fn(), *c_void>(&*start) }; | ||
let sp: *uint = stack.end(); | ||
let sp: *mut uint = unsafe { transmute_mut_unsafe(sp) }; | ||
|
||
// Save and then immediately load the current context, | ||
// which we will then modify to call the given function when restored | ||
let mut regs = new_regs(); | ||
unsafe { | ||
swap_registers(transmute_mut_region(&mut *regs), | ||
transmute_region(&*regs)) | ||
}; | ||
|
||
initialize_call_frame(&mut *regs, fp, argp, sp); | ||
|
||
return Context(regs); | ||
} | ||
|
||
static fn swap(out_context: &mut Context, in_context: &Context) { | ||
let out_regs: &mut Registers = match out_context { | ||
&Context(~ref mut r) => r | ||
}; | ||
let in_regs: &Registers = match in_context { | ||
&Context(~ref r) => r | ||
}; | ||
|
||
unsafe { swap_registers(out_regs, in_regs) }; | ||
} | ||
} | ||
|
||
extern { | ||
fn swap_registers(out_regs: *mut Registers, in_regs: *Registers); | ||
} | ||
|
||
// Definitions of these registers are in rt/arch/x86_64/regs.h | ||
#[cfg(target_arch = "x86_64")] | ||
type Registers = [uint * 22]; | ||
|
||
#[cfg(target_arch = "x86_64")] | ||
fn new_regs() -> ~Registers { ~[0, .. 22] } | ||
|
||
#[cfg(target_arch = "x86_64")] | ||
fn initialize_call_frame(regs: &mut Registers, | ||
fptr: *c_void, arg: *c_void, sp: *mut uint) { | ||
|
||
// Redefinitions from regs.h | ||
const RUSTRT_ARG0: uint = 3; | ||
const RUSTRT_RSP: uint = 1; | ||
const RUSTRT_IP: uint = 8; | ||
const RUSTRT_RBP: uint = 2; | ||
|
||
let sp = align_down(sp); | ||
let sp = mut_offset(sp, -1); | ||
|
||
// The final return address. 0 indicates the bottom of the stack | ||
unsafe { *sp = 0; } | ||
|
||
rtdebug!("creating call frame"); | ||
rtdebug!("fptr %x", fptr as uint); | ||
rtdebug!("arg %x", arg as uint); | ||
rtdebug!("sp %x", sp as uint); | ||
|
||
regs[RUSTRT_ARG0] = arg as uint; | ||
regs[RUSTRT_RSP] = sp as uint; | ||
regs[RUSTRT_IP] = fptr as uint; | ||
|
||
// Last base pointer on the stack should be 0 | ||
regs[RUSTRT_RBP] = 0; | ||
} | ||
|
||
#[cfg(target_arch = "x86")] | ||
struct Registers { | ||
eax: u32, ebx: u32, ecx: u32, edx: u32, | ||
ebp: u32, esi: u32, edi: u32, esp: u32, | ||
cs: u16, ds: u16, ss: u16, es: u16, fs: u16, gs: u16, | ||
eflags: u32, eip: u32 | ||
} | ||
|
||
#[cfg(target_arch = "x86")] | ||
fn new_regs() -> ~Registers { | ||
~Registers { | ||
eax: 0, ebx: 0, ecx: 0, edx: 0, | ||
ebp: 0, esi: 0, edi: 0, esp: 0, | ||
cs: 0, ds: 0, ss: 0, es: 0, fs: 0, gs: 0, | ||
eflags: 0, eip: 0 | ||
} | ||
} | ||
|
||
#[cfg(target_arch = "x86")] | ||
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? | ||
|
||
unsafe { *sp = arg as uint; } | ||
let sp = mut_offset(sp, -1); | ||
unsafe { *sp = 0; } // The final return address | ||
|
||
regs.esp = sp as u32; | ||
regs.eip = fptr as u32; | ||
|
||
// Last base pointer on the stack is 0 | ||
regs.ebp = 0; | ||
} | ||
|
||
fn align_down(sp: *mut uint) -> *mut uint { | ||
unsafe { | ||
let sp = transmute::<*mut uint, uint>(sp); | ||
let sp = sp & !(16 - 1); | ||
transmute::<uint, *mut uint>(sp) | ||
} | ||
} | ||
|
||
// XXX: ptr::offset is positive ints only | ||
#[inline(always)] | ||
pub pure fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T { | ||
use core::sys::size_of; | ||
unsafe { | ||
(ptr as int + count * (size_of::<T>() as int)) as *mut T | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
use option::*; | ||
use result::*; | ||
|
||
// XXX: ~object doesn't work currently so these are some placeholder | ||
// types to use instead | ||
pub type EventLoopObject = super::uvio::UvEventLoop; | ||
pub type IoFactoryObject = super::uvio::UvIoFactory; | ||
pub type StreamObject = super::uvio::UvStream; | ||
pub type TcpListenerObject = super::uvio::UvTcpListener; | ||
|
||
pub trait EventLoop { | ||
fn run(&mut self); | ||
fn callback(&mut self, ~fn()); | ||
/// The asynchronous I/O services. Not all event loops may provide one | ||
fn io(&mut self) -> Option<&self/mut IoFactoryObject>; | ||
} | ||
|
||
pub trait IoFactory { | ||
fn connect(&mut self, addr: IpAddr) -> Option<~StreamObject>; | ||
fn bind(&mut self, addr: IpAddr) -> Option<~TcpListenerObject>; | ||
} | ||
|
||
pub trait TcpListener { | ||
fn listen(&mut self) -> Option<~StreamObject>; | ||
} | ||
|
||
pub trait Stream { | ||
fn read(&mut self, buf: &mut [u8]) -> Result<uint, ()>; | ||
fn write(&mut self, buf: &[u8]) -> Result<(), ()>; | ||
} | ||
|
||
pub enum IpAddr { | ||
Ipv4(u8, u8, u8, u8, u16), | ||
Ipv6 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// XXX: Missing some implementation for other architectures | ||
#[cfg(target_os = "linux")]; | ||
#[cfg(target_os = "mac")]; | ||
#[cfg(target_os = "win32")]; | ||
|
||
// Some basic logging | ||
macro_rules! rtdebug ( | ||
($( $arg:expr),+) => ( { | ||
dumb_println(fmt!( $($arg),+ )); | ||
|
||
fn dumb_println(s: &str) { | ||
use str::as_c_str; | ||
use libc::c_char; | ||
|
||
extern { | ||
fn printf(s: *c_char); | ||
} | ||
|
||
do as_c_str(s.to_str() + "\n") |s| { | ||
unsafe { printf(s); } | ||
} | ||
} | ||
|
||
} ) | ||
) | ||
|
||
// An alternate version with no output, for turning off logging | ||
macro_rules! rtdebug_ ( | ||
($( $arg:expr),+) => ( $(let _ = $arg)*; ) | ||
) | ||
|
||
mod sched; | ||
mod io; | ||
mod uvio; | ||
mod uv; | ||
// FIXME #5248: The import in `sched` doesn't resolve unless this is pub! | ||
pub mod thread_local_storage; | ||
mod work_queue; | ||
mod stack; | ||
mod context; | ||
mod thread; |
Oops, something went wrong.