From b19261a7498155c20b0877e56526e5c018a48be6 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 24 Mar 2014 10:40:36 -0700 Subject: [PATCH 1/3] green: Remove the dependence on the crate map This is the final nail in the coffin for the crate map. The `start` function for libgreen now has a new added parameter which is the event loop factory instead of inferring it from the crate map. The two current valid values for this parameter are `green::basic::event_loop` and `rustuv::event_loop`. --- src/compiletest/compiletest.rs | 4 +- src/libgreen/basic.rs | 4 +- src/libgreen/lib.rs | 69 +++++++++---------- src/libgreen/sched.rs | 8 ++- src/libgreen/task.rs | 2 +- src/libnative/lib.rs | 2 +- src/librustuv/homing.rs | 4 +- src/librustuv/lib.rs | 28 +++++++- src/librustuv/uvio.rs | 6 -- src/libstd/lib.rs | 2 +- .../bootstrap-from-c-with-green/lib.rs | 2 +- src/test/run-pass/core-run-destroy.rs | 2 +- src/test/run-pass/issue-12684.rs | 4 +- src/test/run-pass/issue-8860.rs | 2 +- src/test/run-pass/process-detach.rs | 4 +- 15 files changed, 84 insertions(+), 59 deletions(-) diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index e86309f81af43..69d2b8fb96068 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -44,7 +44,9 @@ pub mod common; pub mod errors; #[start] -fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) } +fn start(argc: int, argv: **u8) -> int { + green::start(argc, argv, rustuv::event_loop, main) +} pub fn main() { let args = os::args(); diff --git a/src/libgreen/basic.rs b/src/libgreen/basic.rs index ba12ca2e04fc5..b2596e568157f 100644 --- a/src/libgreen/basic.rs +++ b/src/libgreen/basic.rs @@ -237,7 +237,7 @@ mod test { fn pool() -> SchedPool { SchedPool::new(PoolConfig { threads: 1, - event_loop_factory: Some(basic::event_loop), + event_loop_factory: basic::event_loop, }) } @@ -267,7 +267,7 @@ mod test { fn multi_thread() { let mut pool = SchedPool::new(PoolConfig { threads: 2, - event_loop_factory: Some(basic::event_loop), + event_loop_factory: basic::event_loop, }); for _ in range(0, 20) { diff --git a/src/libgreen/lib.rs b/src/libgreen/lib.rs index d586d08bd0d75..3f7685d6c20a3 100644 --- a/src/libgreen/lib.rs +++ b/src/libgreen/lib.rs @@ -116,13 +116,34 @@ //! extern crate green; //! //! #[start] -//! fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) } +//! fn start(argc: int, argv: **u8) -> int { +//! green::start(argc, argv, green::basic::event_loop, main) +//! } //! //! fn main() { //! // this code is running in a pool of schedulers //! } //! ``` //! +//! > **Note**: This `main` funciton in this example does *not* have I/O +//! > support. The basic event loop does not provide any support +//! +//! # Starting with I/O support in libgreen +//! +//! ```rust +//! extern crate green; +//! extern crate rustuv; +//! +//! #[start] +//! fn start(argc: int, argv: **u8) -> int { +//! green::start(argc, argv, rustuv::event_loop, main) +//! } +//! +//! fn main() { +//! // this code is running in a pool of schedulers all powered by libuv +//! } +//! ``` +//! //! # Using a scheduler pool //! //! ```rust @@ -176,11 +197,11 @@ #[allow(visible_private_types)]; #[cfg(test)] #[phase(syntax, link)] extern crate log; +#[cfg(test)] extern crate rustuv; extern crate rand; use std::mem::replace; use std::os; -use std::rt::crate_map; use std::rt::rtio; use std::rt::thread::Thread; use std::rt; @@ -207,16 +228,6 @@ pub mod sleeper_list; pub mod stack; pub mod task; -#[lang = "start"] -#[cfg(not(test), stage0)] -pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int { - use std::cast; - start(argc, argv, proc() { - let main: extern "Rust" fn() = unsafe { cast::transmute(main) }; - main(); - }) -} - /// Set up a default runtime configuration, given compiler-supplied arguments. /// /// This function will block until the entire pool of M:N schedulers have @@ -235,12 +246,14 @@ pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int { /// /// The return value is used as the process return code. 0 on success, 101 on /// error. -pub fn start(argc: int, argv: **u8, main: proc()) -> int { +pub fn start(argc: int, argv: **u8, + event_loop_factory: fn() -> ~rtio::EventLoop, + main: proc()) -> int { rt::init(argc, argv); let mut main = Some(main); let mut ret = None; simple::task().run(|| { - ret = Some(run(main.take_unwrap())); + ret = Some(run(event_loop_factory, main.take_unwrap())); }); // unsafe is ok b/c we're sure that the runtime is gone unsafe { rt::cleanup() } @@ -255,10 +268,12 @@ pub fn start(argc: int, argv: **u8, main: proc()) -> int { /// /// This function will not return until all schedulers in the associated pool /// have returned. -pub fn run(main: proc()) -> int { +pub fn run(event_loop_factory: fn() -> ~rtio::EventLoop, main: proc()) -> int { // Create a scheduler pool and spawn the main task into this pool. We will // get notified over a channel when the main task exits. - let mut pool = SchedPool::new(PoolConfig::new()); + let mut cfg = PoolConfig::new(); + cfg.event_loop_factory = event_loop_factory; + let mut pool = SchedPool::new(cfg); let (tx, rx) = channel(); let mut opts = TaskOpts::new(); opts.notify_chan = Some(tx); @@ -283,7 +298,7 @@ pub struct PoolConfig { threads: uint, /// A factory function used to create new event loops. If this is not /// specified then the default event loop factory is used. - event_loop_factory: Option ~rtio::EventLoop>, + event_loop_factory: fn() -> ~rtio::EventLoop, } impl PoolConfig { @@ -292,7 +307,7 @@ impl PoolConfig { pub fn new() -> PoolConfig { PoolConfig { threads: rt::default_sched_threads(), - event_loop_factory: None, + event_loop_factory: basic::event_loop, } } } @@ -334,7 +349,6 @@ impl SchedPool { threads: nscheds, event_loop_factory: factory } = config; - let factory = factory.unwrap_or(default_event_loop_factory()); assert!(nscheds > 0); // The pool of schedulers that will be returned from this function @@ -503,20 +517,3 @@ impl Drop for SchedPool { } } } - -fn default_event_loop_factory() -> fn() -> ~rtio::EventLoop { - match crate_map::get_crate_map() { - None => {} - Some(map) => { - match map.event_loop_factory { - None => {} - Some(factory) => return factory - } - } - } - - // If the crate map didn't specify a factory to create an event loop, then - // instead just use a basic event loop missing all I/O services to at least - // get the scheduler running. - return basic::event_loop; -} diff --git a/src/libgreen/sched.rs b/src/libgreen/sched.rs index 8508b8107a1aa..5571d4f468723 100644 --- a/src/libgreen/sched.rs +++ b/src/libgreen/sched.rs @@ -1003,6 +1003,8 @@ fn new_sched_rng() -> XorShiftRng { #[cfg(test)] mod test { + use rustuv; + use std::comm; use std::task::TaskOpts; use std::rt::Runtime; @@ -1017,7 +1019,7 @@ mod test { fn pool() -> SchedPool { SchedPool::new(PoolConfig { threads: 1, - event_loop_factory: Some(basic::event_loop), + event_loop_factory: basic::event_loop, }) } @@ -1262,7 +1264,7 @@ mod test { let mut pool = SchedPool::new(PoolConfig { threads: 2, - event_loop_factory: None, + event_loop_factory: rustuv::event_loop, }); // This is a regression test that when there are no schedulable tasks in @@ -1413,7 +1415,7 @@ mod test { fn dont_starve_1() { let mut pool = SchedPool::new(PoolConfig { threads: 2, // this must be > 1 - event_loop_factory: Some(basic::event_loop), + event_loop_factory: basic::event_loop, }); pool.spawn(TaskOpts::new(), proc() { let (tx, rx) = channel(); diff --git a/src/libgreen/task.rs b/src/libgreen/task.rs index 97924eca1b9fc..25e868470bf39 100644 --- a/src/libgreen/task.rs +++ b/src/libgreen/task.rs @@ -494,7 +494,7 @@ mod tests { fn spawn_opts(opts: TaskOpts, f: proc()) { let mut pool = SchedPool::new(PoolConfig { threads: 1, - event_loop_factory: None, + event_loop_factory: ::rustuv::event_loop, }); pool.spawn(opts, f); pool.shutdown(); diff --git a/src/libnative/lib.rs b/src/libnative/lib.rs index da8f2ea139d1d..34e85a9819a9a 100644 --- a/src/libnative/lib.rs +++ b/src/libnative/lib.rs @@ -69,7 +69,7 @@ static OS_DEFAULT_STACK_ESTIMATE: uint = 1 << 20; static OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20); #[lang = "start"] -#[cfg(not(test), not(stage0))] +#[cfg(not(test))] pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int { use std::cast; start(argc, argv, proc() { diff --git a/src/librustuv/homing.rs b/src/librustuv/homing.rs index a37d3fd249f9b..3ece7662dd57c 100644 --- a/src/librustuv/homing.rs +++ b/src/librustuv/homing.rs @@ -167,7 +167,7 @@ mod test { let (tx, rx) = channel(); let mut pool = SchedPool::new(PoolConfig { threads: 1, - event_loop_factory: None, + event_loop_factory: ::event_loop, }); pool.spawn(TaskOpts::new(), proc() { @@ -188,7 +188,7 @@ mod test { let (tx, rx) = channel(); let mut pool = SchedPool::new(PoolConfig { threads: 1, - event_loop_factory: None, + event_loop_factory: ::event_loop, }); pool.spawn(TaskOpts::new(), proc() { diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs index 82ca84190f7e5..cf1d95588bb9f 100644 --- a/src/librustuv/lib.rs +++ b/src/librustuv/lib.rs @@ -54,6 +54,7 @@ use std::libc::{c_int, c_void}; use std::ptr::null; use std::ptr; use std::rt::local::Local; +use std::rt::rtio; use std::rt::task::{BlockedTask, Task}; use std::str::raw::from_c_str; use std::str; @@ -76,7 +77,7 @@ pub use self::tty::TtyWatcher; // '__test' module. #[cfg(test)] #[start] fn start(argc: int, argv: **u8) -> int { - green::start(argc, argv, __test::main) + green::start(argc, argv, event_loop, __test::main) } mod macros; @@ -104,6 +105,31 @@ pub mod tty; pub mod signal; pub mod stream; +/// Creates a new event loop which is powered by libuv +/// +/// This function is used in tandem with libgreen's `PoolConfig` type as a value +/// for the `event_loop_factory` field. Using this function as the event loop +/// factory will power programs with libuv and enable green threading. +/// +/// # Example +/// +/// ``` +/// extern crate rustuv; +/// extern crate green; +/// +/// #[start] +/// fn start(argc: int, argv: **u8) -> int { +/// green::start(argc, argv, rustuv::event_loop, main) +/// } +/// +/// fn main() { +/// // this code is running inside of a green task powered by libuv +/// } +/// ``` +pub fn event_loop() -> ~rtio::EventLoop { + ~uvio::UvEventLoop::new() as ~rtio::EventLoop +} + /// A type that wraps a uv handle pub trait UvHandle { fn uv_handle(&self) -> *T; diff --git a/src/librustuv/uvio.rs b/src/librustuv/uvio.rs index e4326fe36bfed..15de040879539 100644 --- a/src/librustuv/uvio.rs +++ b/src/librustuv/uvio.rs @@ -105,12 +105,6 @@ impl rtio::EventLoop for UvEventLoop { } } -#[cfg(not(test))] -#[lang = "event_loop_factory"] -pub fn new_loop() -> ~rtio::EventLoop { - ~UvEventLoop::new() as ~rtio::EventLoop -} - #[test] fn test_callback_run_once() { use std::rt::rtio::EventLoop; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 021a932fc8bbb..9e13d70b0ce18 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -84,7 +84,7 @@ // '__test' module. #[cfg(test)] #[start] fn start(argc: int, argv: **u8) -> int { - green::start(argc, argv, __test::main) + green::start(argc, argv, rustuv::event_loop, __test::main) } pub mod macros; diff --git a/src/test/run-make/bootstrap-from-c-with-green/lib.rs b/src/test/run-make/bootstrap-from-c-with-green/lib.rs index 62c5a06dbbf7b..36b92e127f9d2 100644 --- a/src/test/run-make/bootstrap-from-c-with-green/lib.rs +++ b/src/test/run-make/bootstrap-from-c-with-green/lib.rs @@ -16,7 +16,7 @@ extern crate green; #[no_mangle] // this needs to get called from C pub extern "C" fn foo(argc: int, argv: **u8) -> int { - green::start(argc, argv, proc() { + green::start(argc, argv, rustuv::event_loop, proc() { spawn(proc() { println!("hello"); }); diff --git a/src/test/run-pass/core-run-destroy.rs b/src/test/run-pass/core-run-destroy.rs index bda7a30762a1e..87d3c337bddb0 100644 --- a/src/test/run-pass/core-run-destroy.rs +++ b/src/test/run-pass/core-run-destroy.rs @@ -49,7 +49,7 @@ macro_rules! iotest ( #[cfg(test)] #[start] fn start(argc: int, argv: **u8) -> int { - green::start(argc, argv, __test::main) + green::start(argc, argv, rustuv::event_loop, __test::main) } iotest!(fn test_destroy_once() { diff --git a/src/test/run-pass/issue-12684.rs b/src/test/run-pass/issue-12684.rs index a6eef4e20215f..40c087b5c25b9 100644 --- a/src/test/run-pass/issue-12684.rs +++ b/src/test/run-pass/issue-12684.rs @@ -15,7 +15,9 @@ extern crate green; extern crate rustuv; #[start] -fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) } +fn start(argc: int, argv: **u8) -> int { + green::start(argc, argv, rustuv::event_loop, main) +} fn main() { native::task::spawn(proc() customtask()); diff --git a/src/test/run-pass/issue-8860.rs b/src/test/run-pass/issue-8860.rs index d22de5ce4c80a..d20d0eeb58c82 100644 --- a/src/test/run-pass/issue-8860.rs +++ b/src/test/run-pass/issue-8860.rs @@ -18,7 +18,7 @@ static mut DROP_T: int = 0i; #[start] fn start(argc: int, argv: **u8) -> int { - let ret = green::start(argc, argv, main); + let ret = green::start(argc, argv, green::basic::event_loop, main); unsafe { assert_eq!(2, DROP); assert_eq!(1, DROP_S); diff --git a/src/test/run-pass/process-detach.rs b/src/test/run-pass/process-detach.rs index 319c268201318..3b80d9ce491cc 100644 --- a/src/test/run-pass/process-detach.rs +++ b/src/test/run-pass/process-detach.rs @@ -28,7 +28,9 @@ use std::io::process; use std::io::signal::{Listener, Interrupt}; #[start] -fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) } +fn start(argc: int, argv: **u8) -> int { + green::start(argc, argv, rustuv::event_loop, main) +} fn main() { unsafe { libc::setsid(); } From 3ccad75641515b1fa62dc5378b0b139129aa9daf Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 24 Mar 2014 10:41:43 -0700 Subject: [PATCH 2/3] rustc: Remove all crate map support The crate map is no longer necessary now that logging and event loop factories have been moved out. Closes #11617 Closes #11731 --- src/librustc/driver/session.rs | 2 - src/librustc/middle/lang_items.rs | 2 - src/librustc/middle/lint.rs | 2 +- src/librustc/middle/trans/base.rs | 82 +------------- src/librustc/middle/trans/context.rs | 7 -- src/librustc/middle/trans/foreign.rs | 22 ---- src/libstd/rt/crate_map.rs | 104 ------------------ src/libstd/rt/mod.rs | 3 - .../bootstrap-from-c-with-green/Makefile | 2 +- .../bootstrap-from-c-with-native/Makefile | 2 +- .../c-link-to-rust-staticlib/Makefile | 2 +- .../c-set-crate-map-manually/Makefile | 7 -- .../run-make/c-set-crate-map-manually/lib.rs | 32 ------ .../run-make/c-set-crate-map-manually/main.c | 20 ---- src/test/run-make/lto-smoke-c/Makefile | 2 +- 15 files changed, 6 insertions(+), 285 deletions(-) delete mode 100644 src/libstd/rt/crate_map.rs delete mode 100644 src/test/run-make/c-set-crate-map-manually/Makefile delete mode 100644 src/test/run-make/c-set-crate-map-manually/lib.rs delete mode 100644 src/test/run-make/c-set-crate-map-manually/main.c diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 772d92a4f85ba..d2128810a8bd2 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -451,8 +451,6 @@ cgoptions!( "don't run LLVM's SLP vectorization pass"), soft_float: bool = (false, parse_bool, "generate software floating point library calls"), - gen_crate_map: bool = (false, parse_bool, - "force generation of a toplevel crate map"), prefer_dynamic: bool = (false, parse_bool, "prefer dynamic linking to static linking"), no_integrated_as: bool = (false, parse_bool, diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 67c597f927ac8..2ba408bfa005b 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -254,8 +254,6 @@ lets_do_this! { TyVisitorTraitLangItem, "ty_visitor", ty_visitor; OpaqueStructLangItem, "opaque", opaque; - EventLoopFactoryLangItem, "event_loop_factory", event_loop_factory; - TypeIdLangItem, "type_id", type_id; EhPersonalityLangItem, "eh_personality", eh_personality_fn; diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 2ba8121b479ea..8c20cf39b49fe 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -980,7 +980,7 @@ static other_attrs: &'static [&'static str] = &[ "thread_local", // for statics "allow", "deny", "forbid", "warn", // lint options "deprecated", "experimental", "unstable", "stable", "locked", "frozen", //item stability - "crate_map", "cfg", "doc", "export_name", "link_section", + "cfg", "doc", "export_name", "link_section", "no_mangle", "static_assert", "unsafe_no_drop_flag", "packed", "simd", "repr", "deriving", "unsafe_destructor", "link", "phase", "macro_export", "must_use", "automatically_derived", diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index a00bcdd7037d8..b5e649721153b 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -76,7 +76,7 @@ use std::c_str::ToCStr; use std::cell::{Cell, RefCell}; use std::libc::c_uint; use std::local_data; -use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic, OsWin32}; +use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic}; use syntax::ast_map::PathName; use syntax::ast_util::{local_def, is_local}; use syntax::attr::AttrMetaMethods; @@ -2316,65 +2316,6 @@ pub fn symname(name: &str, hash: &str, vers: &str) -> ~str { link::exported_name(ast_map::Values(path.iter()).chain(None), hash, vers) } -pub fn decl_crate_map(ccx: &mut CrateContext) { - let mut n_subcrates = 1; - while ccx.sess().cstore.have_crate_data(n_subcrates) { - n_subcrates += 1; - } - let is_top = !ccx.sess().building_library.get() || ccx.sess().opts.cg.gen_crate_map; - let sym_name = if is_top { - ~"_rust_crate_map_toplevel" - } else { - symname("_rust_crate_map_" + ccx.link_meta.crateid.name, - ccx.link_meta.crate_hash.as_str(), - ccx.link_meta.crateid.version_or_default()) - }; - - let maptype = Type::struct_(ccx, [ - Type::i32(ccx), // version - ccx.int_type.ptr_to(), // event loop factory - ], false); - let map = sym_name.with_c_str(|buf| { - unsafe { - llvm::LLVMAddGlobal(ccx.llmod, maptype.to_ref(), buf) - } - }); - lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage); - - // On windows we'd like to export the toplevel cratemap - // such that we can find it from libstd. - if ccx.sess().targ_cfg.os == OsWin32 && is_top { - unsafe { llvm::LLVMRustSetDLLExportStorageClass(map) } - } - - ccx.crate_map_name = sym_name; - ccx.crate_map = map; -} - -pub fn fill_crate_map(ccx: &CrateContext, map: ValueRef) { - let event_loop_factory = match ccx.tcx.lang_items.event_loop_factory() { - Some(did) => unsafe { - if is_local(did) { - llvm::LLVMConstPointerCast(get_item_val(ccx, did.node), - ccx.int_type.ptr_to().to_ref()) - } else { - let name = csearch::get_symbol(&ccx.sess().cstore, did); - let global = name.with_c_str(|buf| { - llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf) - }); - global - } - }, - None => C_null(ccx.int_type.ptr_to()) - }; - unsafe { - llvm::LLVMSetInitializer(map, C_struct(ccx, - [C_i32(ccx, 2), - event_loop_factory, - ], false)); - } -} - pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::EncodeInlinedItem<'r>) -> encoder::EncodeParams<'r> { @@ -2467,26 +2408,6 @@ pub fn trans_crate(krate: ast::Crate, trans_mod(&ccx, &krate.module); } - fill_crate_map(&ccx, ccx.crate_map); - - // win32: wart with exporting crate_map symbol - // We set the crate map (_rust_crate_map_toplevel) to use dll_export - // linkage but that ends up causing the linker to look for a - // __rust_crate_map_toplevel symbol (extra underscore) which it will - // subsequently fail to find. So to mitigate that we just introduce - // an alias from the symbol it expects to the one that actually exists. - if ccx.sess().targ_cfg.os == OsWin32 && !ccx.sess().building_library.get() { - - let maptype = val_ty(ccx.crate_map).to_ref(); - - "__rust_crate_map_toplevel".with_c_str(|buf| { - unsafe { - llvm::LLVMAddAlias(ccx.llmod, maptype, - ccx.crate_map, buf); - } - }) - } - glue::emit_tydescs(&ccx); if ccx.sess().opts.debuginfo != NoDebugInfo { debuginfo::finalize(&ccx); @@ -2537,7 +2458,6 @@ pub fn trans_crate(krate: ast::Crate, // symbol. This symbol is required for use by the libmorestack library that // we link in, so we must ensure that this symbol is not internalized (if // defined in the crate). - reachable.push(ccx.crate_map_name.to_owned()); reachable.push(~"main"); reachable.push(~"rust_stack_exhausted"); reachable.push(~"rust_eh_personality"); // referenced from .eh_frame section on some platforms diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index c542556c48f99..a8ff0760eaa4b 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -22,7 +22,6 @@ use middle::trans::base; use middle::trans::builder::Builder; use middle::trans::common::{C_i32, C_null}; use middle::trans::common::{mono_id,ExternMap,tydesc_info,BuilderRef_res,Stats}; -use middle::trans::base::{decl_crate_map}; use middle::trans::debuginfo; use middle::trans::type_::Type; use middle::ty; @@ -105,8 +104,6 @@ pub struct CrateContext { int_type: Type, opaque_vec_type: Type, builder: BuilderRef_res, - crate_map: ValueRef, - crate_map_name: ~str, // Set when at least one function uses GC. Needed so that // decl_gc_metadata knows whether to link to the module metadata, which // is not emitted by LLVM's GC pass when no functions use GC. @@ -200,8 +197,6 @@ impl CrateContext { int_type: Type::from_ref(ptr::null()), opaque_vec_type: Type::from_ref(ptr::null()), builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)), - crate_map: ptr::null(), - crate_map_name: ~"", uses_gc: false, dbg_cx: dbg_cx, }; @@ -215,8 +210,6 @@ impl CrateContext { str_slice_ty.set_struct_body([Type::i8p(&ccx), ccx.int_type], false); ccx.tn.associate_type("str_slice", &str_slice_ty); - decl_crate_map(&mut ccx); - base::declare_intrinsics(&mut ccx); if ccx.sess().count_llvm_insns() { diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 3fd677b34d984..4aa272a63a3e7 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -134,28 +134,6 @@ pub fn register_static(ccx: &CrateContext, let ty = ty::node_id_to_type(ccx.tcx(), foreign_item.id); let llty = type_of::type_of(ccx, ty); - // Treat the crate map static specially in order to - // a weak-linkage-like functionality where it's - // dynamically resolved at runtime. If we're - // building a library, then we declare the static - // with weak linkage, but if we're building a - // library then we've already declared the crate map - // so use that instead. - if attr::contains_name(foreign_item.attrs.as_slice(), "crate_map") { - return if ccx.sess().building_library.get() { - let s = "_rust_crate_map_toplevel"; - let g = unsafe { - s.with_c_str(|buf| { - llvm::LLVMAddGlobal(ccx.llmod, llty.to_ref(), buf) - }) - }; - lib::llvm::SetLinkage(g, lib::llvm::ExternalWeakLinkage); - g - } else { - ccx.crate_map - } - } - let ident = link_name(foreign_item); match attr::first_attr_value_str_by_name(foreign_item.attrs.as_slice(), "linkage") { diff --git a/src/libstd/rt/crate_map.rs b/src/libstd/rt/crate_map.rs deleted file mode 100644 index 98f4986b2c72a..0000000000000 --- a/src/libstd/rt/crate_map.rs +++ /dev/null @@ -1,104 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use cast; -use option::{Some, None, Option}; -use ptr::RawPtr; -use rt::rtio::EventLoop; - -// Need to tell the linker on OS X to not barf on undefined symbols -// and instead look them up at runtime, which we need to resolve -// the crate_map properly. -#[cfg(target_os = "macos")] -#[link_args = "-Wl,-U,__rust_crate_map_toplevel"] -extern {} - -pub struct CrateMap<'a> { - version: i32, - event_loop_factory: Option ~EventLoop>, -} - -// When working on android, apparently weak symbols don't work so well for -// finding the crate map, and neither does dlopen + dlsym. This is mainly a -// problem when integrating a shared library with an existing application. -// Standalone binaries do not appear to have this problem. The reasons are a -// little mysterious, and more information can be found in #11731. -// -// For now we provide a way to tell libstd about the crate map manually that's -// checked before the normal weak symbol/dlopen paths. In theory this is useful -// on other platforms where our dlopen/weak linkage strategy mysteriously fails -// but the crate map can be specified manually. -static mut MANUALLY_PROVIDED_CRATE_MAP: *CrateMap<'static> = - 0 as *CrateMap<'static>; -#[no_mangle] -#[cfg(not(test))] -pub extern fn rust_set_crate_map(map: *CrateMap<'static>) { - unsafe { MANUALLY_PROVIDED_CRATE_MAP = map; } -} - -fn manual_crate_map() -> Option<&'static CrateMap<'static>> { - unsafe { - if MANUALLY_PROVIDED_CRATE_MAP.is_null() { - None - } else { - Some(cast::transmute(MANUALLY_PROVIDED_CRATE_MAP)) - } - } -} - -#[cfg(not(windows))] -pub fn get_crate_map() -> Option<&'static CrateMap<'static>> { - extern { - #[crate_map] - static CRATE_MAP: CrateMap<'static>; - } - - manual_crate_map().or_else(|| { - let ptr: (*CrateMap) = &'static CRATE_MAP; - if ptr.is_null() { - None - } else { - Some(&'static CRATE_MAP) - } - }) -} - -#[cfg(windows)] -pub fn get_crate_map() -> Option<&'static CrateMap<'static>> { - use c_str::ToCStr; - use unstable::dynamic_lib::dl; - - match manual_crate_map() { - Some(cm) => return Some(cm), - None => {} - } - - let sym = unsafe { - let module = dl::open_internal(); - let rust_crate_map_toplevel = if cfg!(target_arch = "x86") { - "__rust_crate_map_toplevel" - } else { - "_rust_crate_map_toplevel" - }; - let sym = rust_crate_map_toplevel.with_c_str(|buf| { - dl::symbol(module, buf) - }); - dl::close(module); - sym - }; - let ptr: (*CrateMap) = sym as *CrateMap; - if ptr.is_null() { - return None; - } else { - unsafe { - return Some(cast::transmute(sym)); - } - } -} diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 84e547619df5a..795281026a426 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -104,9 +104,6 @@ pub mod env; /// The local, managed heap pub mod local_heap; -/// Crate map -pub mod crate_map; - /// The runtime needs to be able to put a pointer into thread-local storage. mod local_ptr; diff --git a/src/test/run-make/bootstrap-from-c-with-green/Makefile b/src/test/run-make/bootstrap-from-c-with-green/Makefile index 2144a2ca57481..43388fd9a6f94 100644 --- a/src/test/run-make/bootstrap-from-c-with-green/Makefile +++ b/src/test/run-make/bootstrap-from-c-with-green/Makefile @@ -1,7 +1,7 @@ -include ../tools.mk all: - $(RUSTC) lib.rs -C gen-crate-map + $(RUSTC) lib.rs ln -nsf $(call DYLIB,boot-*) $(call DYLIB,boot) $(CC) main.c -o $(call RUN,main) -lboot $(call RUN,main) diff --git a/src/test/run-make/bootstrap-from-c-with-native/Makefile b/src/test/run-make/bootstrap-from-c-with-native/Makefile index 2144a2ca57481..43388fd9a6f94 100644 --- a/src/test/run-make/bootstrap-from-c-with-native/Makefile +++ b/src/test/run-make/bootstrap-from-c-with-native/Makefile @@ -1,7 +1,7 @@ -include ../tools.mk all: - $(RUSTC) lib.rs -C gen-crate-map + $(RUSTC) lib.rs ln -nsf $(call DYLIB,boot-*) $(call DYLIB,boot) $(CC) main.c -o $(call RUN,main) -lboot $(call RUN,main) diff --git a/src/test/run-make/c-link-to-rust-staticlib/Makefile b/src/test/run-make/c-link-to-rust-staticlib/Makefile index 6fa5369015bbb..134d15f37aa7e 100644 --- a/src/test/run-make/c-link-to-rust-staticlib/Makefile +++ b/src/test/run-make/c-link-to-rust-staticlib/Makefile @@ -5,7 +5,7 @@ ifneq ($(shell uname),Darwin) endif all: - $(RUSTC) foo.rs -C gen-crate-map + $(RUSTC) foo.rs ln -s $(call STATICLIB,foo-*) $(call STATICLIB,foo) $(CC) bar.c -lfoo -o $(call RUN,bar) $(EXTRAFLAGS) -lstdc++ $(call RUN,bar) diff --git a/src/test/run-make/c-set-crate-map-manually/Makefile b/src/test/run-make/c-set-crate-map-manually/Makefile deleted file mode 100644 index 954f10d3eddfd..0000000000000 --- a/src/test/run-make/c-set-crate-map-manually/Makefile +++ /dev/null @@ -1,7 +0,0 @@ --include ../tools.mk - -all: - $(RUSTC) lib.rs -C gen-crate-map - ln -nsf $(call DYLIB,boot-*) $(call DYLIB,boot) - $(CC) main.c -o $(call RUN,main) -lboot -Wl,-rpath,$(TMPDIR) - RUST_LOG=boot $(call RUN,main) diff --git a/src/test/run-make/c-set-crate-map-manually/lib.rs b/src/test/run-make/c-set-crate-map-manually/lib.rs deleted file mode 100644 index d5bada4a127f9..0000000000000 --- a/src/test/run-make/c-set-crate-map-manually/lib.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[crate_id="boot#0.1"]; -#[crate_type="dylib"]; -#[no_uv]; -#[feature(phase)]; - -extern crate rustuv; -extern crate green; -#[phase(syntax, link)] extern crate log; - -use std::rt::crate_map::{CrateMap, rust_set_crate_map}; - -// pull in this symbol from libstd into this crate (for convenience) -#[no_mangle] -pub static set_crate_map: extern "C" fn(*CrateMap<'static>) = rust_set_crate_map; - -#[no_mangle] // this needs to get called from C -pub extern "C" fn foo(argc: int, argv: **u8) -> int { - green::start(argc, argv, proc() { - if log_enabled!(log::DEBUG) { return } - fail!() - }) -} diff --git a/src/test/run-make/c-set-crate-map-manually/main.c b/src/test/run-make/c-set-crate-map-manually/main.c deleted file mode 100644 index a69ec7d0c86e5..0000000000000 --- a/src/test/run-make/c-set-crate-map-manually/main.c +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// this is the rust entry point that we're going to call. -int foo(int argc, char *argv[]); - -extern void (*set_crate_map)(void *map); -extern int _rust_crate_map_toplevel; - -int main(int argc, char *argv[]) { - set_crate_map(&_rust_crate_map_toplevel); - return foo(argc, argv); -} diff --git a/src/test/run-make/lto-smoke-c/Makefile b/src/test/run-make/lto-smoke-c/Makefile index af120c9baebba..6a70392773652 100644 --- a/src/test/run-make/lto-smoke-c/Makefile +++ b/src/test/run-make/lto-smoke-c/Makefile @@ -5,7 +5,7 @@ ifneq ($(shell uname),Darwin) endif all: - $(RUSTC) foo.rs -C gen-crate-map -Z lto + $(RUSTC) foo.rs -Z lto ln -s $(call STATICLIB,foo-*) $(call STATICLIB,foo) $(CC) bar.c -lfoo -o $(call RUN,bar) $(EXTRAFLAGS) -lstdc++ $(call RUN,bar) From e2ae4585481879290879e46881916ce6e3dd22c1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 24 Mar 2014 10:51:13 -0700 Subject: [PATCH 3/3] doc: Update the runtime guide with green changes This updates a few code examples about booting libgreen/libnative and also spells out how the event loop factory is required. --- src/doc/guide-runtime.md | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/doc/guide-runtime.md b/src/doc/guide-runtime.md index 6d5d90e2617fe..b52c520761e23 100644 --- a/src/doc/guide-runtime.md +++ b/src/doc/guide-runtime.md @@ -223,27 +223,49 @@ Having a default decision made in the compiler is done out of necessity and convenience. The compiler's decision of runtime to link to is *not* an endorsement of one over the other. As always, this decision can be overridden. -For example, this program will be linked to "the default runtime" +For example, this program will be linked to "the default runtime". The current +default runtime is to use libnative. ~~~{.rust} fn main() {} ~~~ -Whereas this program explicitly opts into using a particular runtime +### Force booting with libgreen + +In this example, the `main` function will be booted with I/O support powered by +libuv. This is done by linking to the `rustuv` crate and specifying the +`rustuv::event_loop` function as the event loop factory. + +To create a pool of green tasks which have no I/O support, you may shed the +`rustuv` dependency and use the `green::basic::event_loop` function instead of +`rustuv::event_loop`. All tasks will have no I/O support, but they will still be +able to deschedule/reschedule (use channels, locks, etc). ~~~{.rust} extern crate green; +extern crate rustuv; #[start] fn start(argc: int, argv: **u8) -> int { - green::start(argc, argv, main) + green::start(argc, argv, rustuv::event_loop, main) } fn main() {} ~~~ -Both libgreen/libnative provide a top-level `start` function which is used to -boot an initial Rust task in that specified runtime. +### Force booting with libnative + +This program's `main` function will always be booted with libnative, running +inside of an OS thread. + +~~~{.rust} +extern crate native; + +#[start] +fn start(argc: int, argv: **u8) -> int { native::start(argc, argv, main) } + +fn main() {} +~~~ # Finding the runtime