Skip to content

Commit de85948

Browse files
committed
auto merge of #13117 : alexcrichton/rust/no-crate-map, r=brson
This can be done now that logging has been moved out and libnative is the default (not libgreen)
2 parents 6bac560 + e2ae458 commit de85948

File tree

30 files changed

+116
-338
lines changed

30 files changed

+116
-338
lines changed

src/compiletest/compiletest.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ pub mod common;
4343
pub mod errors;
4444

4545
#[start]
46-
fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) }
46+
fn start(argc: int, argv: **u8) -> int {
47+
green::start(argc, argv, rustuv::event_loop, main)
48+
}
4749

4850
pub fn main() {
4951
let args = os::args();

src/doc/guide-runtime.md

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -223,27 +223,49 @@ Having a default decision made in the compiler is done out of necessity and
223223
convenience. The compiler's decision of runtime to link to is *not* an
224224
endorsement of one over the other. As always, this decision can be overridden.
225225

226-
For example, this program will be linked to "the default runtime"
226+
For example, this program will be linked to "the default runtime". The current
227+
default runtime is to use libnative.
227228

228229
~~~{.rust}
229230
fn main() {}
230231
~~~
231232

232-
Whereas this program explicitly opts into using a particular runtime
233+
### Force booting with libgreen
234+
235+
In this example, the `main` function will be booted with I/O support powered by
236+
libuv. This is done by linking to the `rustuv` crate and specifying the
237+
`rustuv::event_loop` function as the event loop factory.
238+
239+
To create a pool of green tasks which have no I/O support, you may shed the
240+
`rustuv` dependency and use the `green::basic::event_loop` function instead of
241+
`rustuv::event_loop`. All tasks will have no I/O support, but they will still be
242+
able to deschedule/reschedule (use channels, locks, etc).
233243

234244
~~~{.rust}
235245
extern crate green;
246+
extern crate rustuv;
236247
237248
#[start]
238249
fn start(argc: int, argv: **u8) -> int {
239-
green::start(argc, argv, main)
250+
green::start(argc, argv, rustuv::event_loop, main)
240251
}
241252
242253
fn main() {}
243254
~~~
244255

245-
Both libgreen/libnative provide a top-level `start` function which is used to
246-
boot an initial Rust task in that specified runtime.
256+
### Force booting with libnative
257+
258+
This program's `main` function will always be booted with libnative, running
259+
inside of an OS thread.
260+
261+
~~~{.rust}
262+
extern crate native;
263+
264+
#[start]
265+
fn start(argc: int, argv: **u8) -> int { native::start(argc, argv, main) }
266+
267+
fn main() {}
268+
~~~
247269

248270
# Finding the runtime
249271

src/libgreen/basic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ mod test {
237237
fn pool() -> SchedPool {
238238
SchedPool::new(PoolConfig {
239239
threads: 1,
240-
event_loop_factory: Some(basic::event_loop),
240+
event_loop_factory: basic::event_loop,
241241
})
242242
}
243243

@@ -267,7 +267,7 @@ mod test {
267267
fn multi_thread() {
268268
let mut pool = SchedPool::new(PoolConfig {
269269
threads: 2,
270-
event_loop_factory: Some(basic::event_loop),
270+
event_loop_factory: basic::event_loop,
271271
});
272272

273273
for _ in range(0, 20) {

src/libgreen/lib.rs

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,34 @@
116116
//! extern crate green;
117117
//!
118118
//! #[start]
119-
//! fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) }
119+
//! fn start(argc: int, argv: **u8) -> int {
120+
//! green::start(argc, argv, green::basic::event_loop, main)
121+
//! }
120122
//!
121123
//! fn main() {
122124
//! // this code is running in a pool of schedulers
123125
//! }
124126
//! ```
125127
//!
128+
//! > **Note**: This `main` funciton in this example does *not* have I/O
129+
//! > support. The basic event loop does not provide any support
130+
//!
131+
//! # Starting with I/O support in libgreen
132+
//!
133+
//! ```rust
134+
//! extern crate green;
135+
//! extern crate rustuv;
136+
//!
137+
//! #[start]
138+
//! fn start(argc: int, argv: **u8) -> int {
139+
//! green::start(argc, argv, rustuv::event_loop, main)
140+
//! }
141+
//!
142+
//! fn main() {
143+
//! // this code is running in a pool of schedulers all powered by libuv
144+
//! }
145+
//! ```
146+
//!
126147
//! # Using a scheduler pool
127148
//!
128149
//! ```rust
@@ -176,11 +197,11 @@
176197
#[allow(visible_private_types)];
177198

178199
#[cfg(test)] #[phase(syntax, link)] extern crate log;
200+
#[cfg(test)] extern crate rustuv;
179201
extern crate rand;
180202

181203
use std::mem::replace;
182204
use std::os;
183-
use std::rt::crate_map;
184205
use std::rt::rtio;
185206
use std::rt::thread::Thread;
186207
use std::rt;
@@ -225,12 +246,14 @@ pub mod task;
225246
///
226247
/// The return value is used as the process return code. 0 on success, 101 on
227248
/// error.
228-
pub fn start(argc: int, argv: **u8, main: proc()) -> int {
249+
pub fn start(argc: int, argv: **u8,
250+
event_loop_factory: fn() -> ~rtio::EventLoop,
251+
main: proc()) -> int {
229252
rt::init(argc, argv);
230253
let mut main = Some(main);
231254
let mut ret = None;
232255
simple::task().run(|| {
233-
ret = Some(run(main.take_unwrap()));
256+
ret = Some(run(event_loop_factory, main.take_unwrap()));
234257
});
235258
// unsafe is ok b/c we're sure that the runtime is gone
236259
unsafe { rt::cleanup() }
@@ -245,10 +268,12 @@ pub fn start(argc: int, argv: **u8, main: proc()) -> int {
245268
///
246269
/// This function will not return until all schedulers in the associated pool
247270
/// have returned.
248-
pub fn run(main: proc()) -> int {
271+
pub fn run(event_loop_factory: fn() -> ~rtio::EventLoop, main: proc()) -> int {
249272
// Create a scheduler pool and spawn the main task into this pool. We will
250273
// get notified over a channel when the main task exits.
251-
let mut pool = SchedPool::new(PoolConfig::new());
274+
let mut cfg = PoolConfig::new();
275+
cfg.event_loop_factory = event_loop_factory;
276+
let mut pool = SchedPool::new(cfg);
252277
let (tx, rx) = channel();
253278
let mut opts = TaskOpts::new();
254279
opts.notify_chan = Some(tx);
@@ -273,7 +298,7 @@ pub struct PoolConfig {
273298
threads: uint,
274299
/// A factory function used to create new event loops. If this is not
275300
/// specified then the default event loop factory is used.
276-
event_loop_factory: Option<fn() -> ~rtio::EventLoop>,
301+
event_loop_factory: fn() -> ~rtio::EventLoop,
277302
}
278303

279304
impl PoolConfig {
@@ -282,7 +307,7 @@ impl PoolConfig {
282307
pub fn new() -> PoolConfig {
283308
PoolConfig {
284309
threads: rt::default_sched_threads(),
285-
event_loop_factory: None,
310+
event_loop_factory: basic::event_loop,
286311
}
287312
}
288313
}
@@ -324,7 +349,6 @@ impl SchedPool {
324349
threads: nscheds,
325350
event_loop_factory: factory
326351
} = config;
327-
let factory = factory.unwrap_or(default_event_loop_factory());
328352
assert!(nscheds > 0);
329353

330354
// The pool of schedulers that will be returned from this function
@@ -493,20 +517,3 @@ impl Drop for SchedPool {
493517
}
494518
}
495519
}
496-
497-
fn default_event_loop_factory() -> fn() -> ~rtio::EventLoop {
498-
match crate_map::get_crate_map() {
499-
None => {}
500-
Some(map) => {
501-
match map.event_loop_factory {
502-
None => {}
503-
Some(factory) => return factory
504-
}
505-
}
506-
}
507-
508-
// If the crate map didn't specify a factory to create an event loop, then
509-
// instead just use a basic event loop missing all I/O services to at least
510-
// get the scheduler running.
511-
return basic::event_loop;
512-
}

src/libgreen/sched.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,8 @@ fn new_sched_rng() -> XorShiftRng {
10031003

10041004
#[cfg(test)]
10051005
mod test {
1006+
use rustuv;
1007+
10061008
use std::comm;
10071009
use std::task::TaskOpts;
10081010
use std::rt::Runtime;
@@ -1017,7 +1019,7 @@ mod test {
10171019
fn pool() -> SchedPool {
10181020
SchedPool::new(PoolConfig {
10191021
threads: 1,
1020-
event_loop_factory: Some(basic::event_loop),
1022+
event_loop_factory: basic::event_loop,
10211023
})
10221024
}
10231025

@@ -1262,7 +1264,7 @@ mod test {
12621264

12631265
let mut pool = SchedPool::new(PoolConfig {
12641266
threads: 2,
1265-
event_loop_factory: None,
1267+
event_loop_factory: rustuv::event_loop,
12661268
});
12671269

12681270
// This is a regression test that when there are no schedulable tasks in
@@ -1413,7 +1415,7 @@ mod test {
14131415
fn dont_starve_1() {
14141416
let mut pool = SchedPool::new(PoolConfig {
14151417
threads: 2, // this must be > 1
1416-
event_loop_factory: Some(basic::event_loop),
1418+
event_loop_factory: basic::event_loop,
14171419
});
14181420
pool.spawn(TaskOpts::new(), proc() {
14191421
let (tx, rx) = channel();

src/libgreen/task.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ mod tests {
494494
fn spawn_opts(opts: TaskOpts, f: proc()) {
495495
let mut pool = SchedPool::new(PoolConfig {
496496
threads: 1,
497-
event_loop_factory: None,
497+
event_loop_factory: ::rustuv::event_loop,
498498
});
499499
pool.spawn(opts, f);
500500
pool.shutdown();

src/librustc/driver/session.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,6 @@ cgoptions!(
451451
"don't run LLVM's SLP vectorization pass"),
452452
soft_float: bool = (false, parse_bool,
453453
"generate software floating point library calls"),
454-
gen_crate_map: bool = (false, parse_bool,
455-
"force generation of a toplevel crate map"),
456454
prefer_dynamic: bool = (false, parse_bool,
457455
"prefer dynamic linking to static linking"),
458456
no_integrated_as: bool = (false, parse_bool,

src/librustc/middle/lang_items.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,6 @@ lets_do_this! {
254254
TyVisitorTraitLangItem, "ty_visitor", ty_visitor;
255255
OpaqueStructLangItem, "opaque", opaque;
256256

257-
EventLoopFactoryLangItem, "event_loop_factory", event_loop_factory;
258-
259257
TypeIdLangItem, "type_id", type_id;
260258

261259
EhPersonalityLangItem, "eh_personality", eh_personality_fn;

src/librustc/middle/lint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,7 @@ static other_attrs: &'static [&'static str] = &[
980980
"thread_local", // for statics
981981
"allow", "deny", "forbid", "warn", // lint options
982982
"deprecated", "experimental", "unstable", "stable", "locked", "frozen", //item stability
983-
"crate_map", "cfg", "doc", "export_name", "link_section",
983+
"cfg", "doc", "export_name", "link_section",
984984
"no_mangle", "static_assert", "unsafe_no_drop_flag", "packed",
985985
"simd", "repr", "deriving", "unsafe_destructor", "link", "phase",
986986
"macro_export", "must_use", "automatically_derived",

src/librustc/middle/trans/base.rs

Lines changed: 1 addition & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ use std::c_str::ToCStr;
7676
use std::cell::{Cell, RefCell};
7777
use std::libc::c_uint;
7878
use std::local_data;
79-
use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic, OsWin32};
79+
use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic};
8080
use syntax::ast_map::PathName;
8181
use syntax::ast_util::{local_def, is_local};
8282
use syntax::attr::AttrMetaMethods;
@@ -2316,65 +2316,6 @@ pub fn symname(name: &str, hash: &str, vers: &str) -> ~str {
23162316
link::exported_name(ast_map::Values(path.iter()).chain(None), hash, vers)
23172317
}
23182318

2319-
pub fn decl_crate_map(ccx: &mut CrateContext) {
2320-
let mut n_subcrates = 1;
2321-
while ccx.sess().cstore.have_crate_data(n_subcrates) {
2322-
n_subcrates += 1;
2323-
}
2324-
let is_top = !ccx.sess().building_library.get() || ccx.sess().opts.cg.gen_crate_map;
2325-
let sym_name = if is_top {
2326-
~"_rust_crate_map_toplevel"
2327-
} else {
2328-
symname("_rust_crate_map_" + ccx.link_meta.crateid.name,
2329-
ccx.link_meta.crate_hash.as_str(),
2330-
ccx.link_meta.crateid.version_or_default())
2331-
};
2332-
2333-
let maptype = Type::struct_(ccx, [
2334-
Type::i32(ccx), // version
2335-
ccx.int_type.ptr_to(), // event loop factory
2336-
], false);
2337-
let map = sym_name.with_c_str(|buf| {
2338-
unsafe {
2339-
llvm::LLVMAddGlobal(ccx.llmod, maptype.to_ref(), buf)
2340-
}
2341-
});
2342-
lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
2343-
2344-
// On windows we'd like to export the toplevel cratemap
2345-
// such that we can find it from libstd.
2346-
if ccx.sess().targ_cfg.os == OsWin32 && is_top {
2347-
unsafe { llvm::LLVMRustSetDLLExportStorageClass(map) }
2348-
}
2349-
2350-
ccx.crate_map_name = sym_name;
2351-
ccx.crate_map = map;
2352-
}
2353-
2354-
pub fn fill_crate_map(ccx: &CrateContext, map: ValueRef) {
2355-
let event_loop_factory = match ccx.tcx.lang_items.event_loop_factory() {
2356-
Some(did) => unsafe {
2357-
if is_local(did) {
2358-
llvm::LLVMConstPointerCast(get_item_val(ccx, did.node),
2359-
ccx.int_type.ptr_to().to_ref())
2360-
} else {
2361-
let name = csearch::get_symbol(&ccx.sess().cstore, did);
2362-
let global = name.with_c_str(|buf| {
2363-
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf)
2364-
});
2365-
global
2366-
}
2367-
},
2368-
None => C_null(ccx.int_type.ptr_to())
2369-
};
2370-
unsafe {
2371-
llvm::LLVMSetInitializer(map, C_struct(ccx,
2372-
[C_i32(ccx, 2),
2373-
event_loop_factory,
2374-
], false));
2375-
}
2376-
}
2377-
23782319
pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::EncodeInlinedItem<'r>)
23792320
-> encoder::EncodeParams<'r> {
23802321

@@ -2467,26 +2408,6 @@ pub fn trans_crate(krate: ast::Crate,
24672408
trans_mod(&ccx, &krate.module);
24682409
}
24692410

2470-
fill_crate_map(&ccx, ccx.crate_map);
2471-
2472-
// win32: wart with exporting crate_map symbol
2473-
// We set the crate map (_rust_crate_map_toplevel) to use dll_export
2474-
// linkage but that ends up causing the linker to look for a
2475-
// __rust_crate_map_toplevel symbol (extra underscore) which it will
2476-
// subsequently fail to find. So to mitigate that we just introduce
2477-
// an alias from the symbol it expects to the one that actually exists.
2478-
if ccx.sess().targ_cfg.os == OsWin32 && !ccx.sess().building_library.get() {
2479-
2480-
let maptype = val_ty(ccx.crate_map).to_ref();
2481-
2482-
"__rust_crate_map_toplevel".with_c_str(|buf| {
2483-
unsafe {
2484-
llvm::LLVMAddAlias(ccx.llmod, maptype,
2485-
ccx.crate_map, buf);
2486-
}
2487-
})
2488-
}
2489-
24902411
glue::emit_tydescs(&ccx);
24912412
if ccx.sess().opts.debuginfo != NoDebugInfo {
24922413
debuginfo::finalize(&ccx);
@@ -2537,7 +2458,6 @@ pub fn trans_crate(krate: ast::Crate,
25372458
// symbol. This symbol is required for use by the libmorestack library that
25382459
// we link in, so we must ensure that this symbol is not internalized (if
25392460
// defined in the crate).
2540-
reachable.push(ccx.crate_map_name.to_owned());
25412461
reachable.push(~"main");
25422462
reachable.push(~"rust_stack_exhausted");
25432463
reachable.push(~"rust_eh_personality"); // referenced from .eh_frame section on some platforms

0 commit comments

Comments
 (0)