Test fixes and rebase problems

Note that this removes a number of run-pass tests which are exercising behavior
of the old runtime. This functionality no longer exists and is thoroughly tested
inside of libgreen and libnative. There isn't really the notion of "starting the
runtime" any more. The major notion now is "bootstrapping the initial task".
This commit is contained in:
Alex Crichton 2013-12-13 21:14:08 -08:00
parent 39dbcd7b01
commit 282f3d99a5
18 changed files with 134 additions and 107 deletions

View File

@ -280,9 +280,15 @@ define CHECK_FOR_OLD_GLOB_MATCHES_EXCEPT
endef endef
# Same interface as above, but deletes rather than just listing the files. # Same interface as above, but deletes rather than just listing the files.
ifdef VERBOSE
define REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT define REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT
$(Q)MATCHES="$(filter-out %$(3),$(wildcard $(1)/$(2)))"; if [ -n "$$MATCHES" ] ; then echo "warning: removing previous" \'$(2)\' "libraries:" $$MATCHES; rm $$MATCHES ; fi $(Q)MATCHES="$(filter-out %$(3),$(wildcard $(1)/$(2)))"; if [ -n "$$MATCHES" ] ; then echo "warning: removing previous" \'$(2)\' "libraries:" $$MATCHES; rm $$MATCHES ; fi
endef endef
else
define REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT
$(Q)MATCHES="$(filter-out %$(3),$(wildcard $(1)/$(2)))"; if [ -n "$$MATCHES" ] ; then rm $$MATCHES ; fi
endef
endif
# We use a different strategy for LIST_ALL_OLD_GLOB_MATCHES_EXCEPT # We use a different strategy for LIST_ALL_OLD_GLOB_MATCHES_EXCEPT
# than in the macros above because it needs the result of running the # than in the macros above because it needs the result of running the

View File

@ -161,16 +161,13 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(3)): \
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_GLOB_$(2)),$$(notdir $$@)) $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_GLOB_$(2)),$$(notdir $$@))
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_RGLOB_$(2)),$$(notdir $$@)) $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_RGLOB_$(2)),$$(notdir $$@))
# NOTE: after the next snapshot remove these '-L' flags
$$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X_$(3)): \ $$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X_$(3)): \
$$(DRIVER_CRATE) \ $$(DRIVER_CRATE) \
$$(TSREQ$(1)_T_$(2)_H_$(3)) \ $$(SREQ$(1)_T_$(2)_H_$(3)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(3)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(3)) \
| $$(TBIN$(1)_T_$(2)_H_$(3))/ | $$(TBIN$(1)_T_$(2)_H_$(3))/
@$$(call E, compile_and_link: $$@) @$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(2)_H_$(3)) --cfg rustc -o $$@ $$< \ $$(STAGE$(1)_T_$(2)_H_$(3)) --cfg rustc -o $$@ $$<
-L $$(UV_SUPPORT_DIR_$(2)) \
-L $$(dir $$(LIBUV_LIB_$(2)))
ifdef CFG_ENABLE_PAX_FLAGS ifdef CFG_ENABLE_PAX_FLAGS
@$$(call E, apply PaX flags: $$@) @$$(call E, apply PaX flags: $$@)
@"$(CFG_PAXCTL)" -cm "$$@" @"$(CFG_PAXCTL)" -cm "$$@"

View File

@ -16,7 +16,7 @@
extern mod extra; extern mod extra;
use std::os; use std::os;
use std::rt; use std::io;
use std::io::fs; use std::io::fs;
use extra::getopts; use extra::getopts;
@ -234,7 +234,7 @@ pub fn run_tests(config: &config) {
// sadly osx needs some file descriptor limits raised for running tests in // sadly osx needs some file descriptor limits raised for running tests in
// parallel (especially when we have lots and lots of child processes). // parallel (especially when we have lots and lots of child processes).
// For context, see #8904 // For context, see #8904
rt::test::prepare_for_lots_of_tests(); io::test::raise_fd_limit();
let res = test::run_tests_console(&opts, tests); let res = test::run_tests_console(&opts, tests);
if !res { fail!("Some tests failed"); } if !res { fail!("Some tests failed"); }
} }

View File

@ -76,9 +76,9 @@ exceptions = [
"rt/isaac/randport.cpp", # public domain "rt/isaac/randport.cpp", # public domain
"rt/isaac/rand.h", # public domain "rt/isaac/rand.h", # public domain
"rt/isaac/standard.h", # public domain "rt/isaac/standard.h", # public domain
"libstd/rt/mpsc_queue.rs", # BSD "libstd/sync/mpsc_queue.rs", # BSD
"libstd/rt/spsc_queue.rs", # BSD "libstd/sync/spsc_queue.rs", # BSD
"libstd/rt/mpmc_bounded_queue.rs", # BSD "libstd/sync/mpmc_bounded_queue.rs", # BSD
] ]
def check_license(name, contents): def check_license(name, contents):

View File

@ -17,6 +17,7 @@
//! This can be optionally linked in to rust programs in order to provide M:N //! This can be optionally linked in to rust programs in order to provide M:N
//! functionality inside of 1:1 programs. //! functionality inside of 1:1 programs.
#[pkgid = "green#0.9-pre"];
#[link(name = "green", #[link(name = "green",
package_id = "green", package_id = "green",
vers = "0.9-pre", vers = "0.9-pre",
@ -30,17 +31,16 @@
// NB this does *not* include globs, please keep it that way. // NB this does *not* include globs, please keep it that way.
#[feature(macro_rules)]; #[feature(macro_rules)];
use std::cast;
use std::os; use std::os;
use std::rt::thread::Thread;
use std::rt;
use std::rt::crate_map; use std::rt::crate_map;
use std::rt::rtio; use std::rt::rtio;
use std::sync::deque; use std::rt::thread::Thread;
use std::rt;
use std::sync::atomics::{SeqCst, AtomicUint, INIT_ATOMIC_UINT}; use std::sync::atomics::{SeqCst, AtomicUint, INIT_ATOMIC_UINT};
use std::sync::deque;
use std::task::TaskOpts; use std::task::TaskOpts;
use std::vec;
use std::util; use std::util;
use std::vec;
use stdtask = std::rt::task; use stdtask = std::rt::task;
use sched::{Shutdown, Scheduler, SchedHandle, TaskFromFriend, NewNeighbor}; use sched::{Shutdown, Scheduler, SchedHandle, TaskFromFriend, NewNeighbor};
@ -58,9 +58,9 @@ pub mod sleeper_list;
pub mod stack; pub mod stack;
pub mod task; pub mod task;
#[cfg(stage0)]
#[lang = "start"] #[lang = "start"]
pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int { pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
use std::cast;
do start(argc, argv) { do start(argc, argv) {
let main: extern "Rust" fn() = unsafe { cast::transmute(main) }; let main: extern "Rust" fn() = unsafe { cast::transmute(main) };
main(); main();
@ -103,7 +103,15 @@ pub fn start(argc: int, argv: **u8, main: proc()) -> int {
/// have returned. /// have returned.
pub fn run(main: proc()) -> int { pub fn run(main: proc()) -> int {
let mut pool = SchedPool::new(PoolConfig::new()); let mut pool = SchedPool::new(PoolConfig::new());
pool.spawn(TaskOpts::new(), main); let (port, chan) = Chan::new();
let mut opts = TaskOpts::new();
opts.notify_chan = Some(chan);
pool.spawn(opts, main);
do pool.spawn(TaskOpts::new()) {
if port.recv().is_err() {
os::set_exit_status(rt::DEFAULT_ERROR_CODE);
}
}
unsafe { stdtask::wait_for_completion(); } unsafe { stdtask::wait_for_completion(); }
pool.shutdown(); pool.shutdown();
os::get_exit_status() os::get_exit_status()

View File

@ -14,6 +14,7 @@
//! runtime. In addition, all I/O provided by this crate is the thread blocking //! runtime. In addition, all I/O provided by this crate is the thread blocking
//! version of I/O. //! version of I/O.
#[pkgid = "native#0.9-pre"];
#[link(name = "native", #[link(name = "native",
package_id = "native", package_id = "native",
vers = "0.9-pre", vers = "0.9-pre",
@ -24,6 +25,7 @@
#[crate_type = "rlib"]; #[crate_type = "rlib"];
#[crate_type = "dylib"]; #[crate_type = "dylib"];
// Allow check-stage0-native for now
#[cfg(stage0, test)] extern mod green; #[cfg(stage0, test)] extern mod green;
// NB this crate explicitly does *not* allow glob imports, please seriously // NB this crate explicitly does *not* allow glob imports, please seriously

View File

@ -31,6 +31,8 @@
//! This enqueueing is done with a concurrent queue from libstd, and the //! This enqueueing is done with a concurrent queue from libstd, and the
//! signalling is achieved with an async handle. //! signalling is achieved with an async handle.
#[allow(dead_code)];
use std::rt::local::Local; use std::rt::local::Local;
use std::rt::rtio::LocalIo; use std::rt::rtio::LocalIo;
use std::rt::task::{Task, BlockedTask}; use std::rt::task::{Task, BlockedTask};

View File

@ -18,6 +18,8 @@
//! event loop alive we use uv_ref and uv_unref in order to control when the //! event loop alive we use uv_ref and uv_unref in order to control when the
//! async handle is active or not. //! async handle is active or not.
#[allow(dead_code)];
use std::cast; use std::cast;
use std::libc::{c_void, c_int}; use std::libc::{c_void, c_int};
use std::rt::task::BlockedTask; use std::rt::task::BlockedTask;

View File

@ -113,3 +113,82 @@ fn base_port() -> u16 {
return final_base; return final_base;
} }
pub fn raise_fd_limit() {
unsafe { darwin_fd_limit::raise_fd_limit() }
}
#[cfg(target_os="macos")]
#[allow(non_camel_case_types)]
mod darwin_fd_limit {
/*!
* darwin_fd_limit exists to work around an issue where launchctl on Mac OS X defaults the
* rlimit maxfiles to 256/unlimited. The default soft limit of 256 ends up being far too low
* for our multithreaded scheduler testing, depending on the number of cores available.
*
* This fixes issue #7772.
*/
use libc;
type rlim_t = libc::uint64_t;
struct rlimit {
rlim_cur: rlim_t,
rlim_max: rlim_t
}
#[nolink]
extern {
// name probably doesn't need to be mut, but the C function doesn't specify const
fn sysctl(name: *mut libc::c_int, namelen: libc::c_uint,
oldp: *mut libc::c_void, oldlenp: *mut libc::size_t,
newp: *mut libc::c_void, newlen: libc::size_t) -> libc::c_int;
fn getrlimit(resource: libc::c_int, rlp: *mut rlimit) -> libc::c_int;
fn setrlimit(resource: libc::c_int, rlp: *rlimit) -> libc::c_int;
}
static CTL_KERN: libc::c_int = 1;
static KERN_MAXFILESPERPROC: libc::c_int = 29;
static RLIMIT_NOFILE: libc::c_int = 8;
pub unsafe fn raise_fd_limit() {
// The strategy here is to fetch the current resource limits, read the kern.maxfilesperproc
// sysctl value, and bump the soft resource limit for maxfiles up to the sysctl value.
use ptr::{to_unsafe_ptr, to_mut_unsafe_ptr, mut_null};
use mem::size_of_val;
use os::last_os_error;
// Fetch the kern.maxfilesperproc value
let mut mib: [libc::c_int, ..2] = [CTL_KERN, KERN_MAXFILESPERPROC];
let mut maxfiles: libc::c_int = 0;
let mut size: libc::size_t = size_of_val(&maxfiles) as libc::size_t;
if sysctl(to_mut_unsafe_ptr(&mut mib[0]), 2,
to_mut_unsafe_ptr(&mut maxfiles) as *mut libc::c_void,
to_mut_unsafe_ptr(&mut size),
mut_null(), 0) != 0 {
let err = last_os_error();
error!("raise_fd_limit: error calling sysctl: {}", err);
return;
}
// Fetch the current resource limits
let mut rlim = rlimit{rlim_cur: 0, rlim_max: 0};
if getrlimit(RLIMIT_NOFILE, to_mut_unsafe_ptr(&mut rlim)) != 0 {
let err = last_os_error();
error!("raise_fd_limit: error calling getrlimit: {}", err);
return;
}
// Bump the soft limit to the smaller of kern.maxfilesperproc and the hard limit
rlim.rlim_cur = ::cmp::min(maxfiles as rlim_t, rlim.rlim_max);
// Set our newly-increased resource limit
if setrlimit(RLIMIT_NOFILE, to_unsafe_ptr(&rlim)) != 0 {
let err = last_os_error();
error!("raise_fd_limit: error calling setrlimit: {}", err);
return;
}
}
}
#[cfg(not(target_os="macos"))]
mod darwin_fd_limit {
pub unsafe fn raise_fd_limit() {}
}

View File

@ -38,8 +38,13 @@ use task::{TaskResult, TaskOpts};
use unstable::finally::Finally; use unstable::finally::Finally;
use unstable::mutex::{Mutex, MUTEX_INIT}; use unstable::mutex::{Mutex, MUTEX_INIT};
#[cfg(stage0)] pub use rt::unwind::begin_unwind; #[cfg(stage0)]
pub use rt::unwind::begin_unwind;
// These two statics are used as bookeeping to keep track of the rust runtime's
// count of threads. In 1:1 contexts, this is used to know when to return from
// the main function, and in M:N contexts this is used to know when to shut down
// the pool of schedulers.
static mut TASK_COUNT: AtomicUint = INIT_ATOMIC_UINT; static mut TASK_COUNT: AtomicUint = INIT_ATOMIC_UINT;
static mut TASK_LOCK: Mutex = MUTEX_INIT; static mut TASK_LOCK: Mutex = MUTEX_INIT;
@ -181,10 +186,15 @@ impl Task {
// Cleanup the dynamic borrowck debugging info // Cleanup the dynamic borrowck debugging info
borrowck::clear_task_borrow_list(); borrowck::clear_task_borrow_list();
// TODO: dox // Here we must unsafely borrow the task in order to not remove it from
// TLS. When collecting failure, we may attempt to send on a channel (or
// just run aribitrary code), so we must be sure to still have a local
// task in TLS.
unsafe { unsafe {
let me: *mut Task = Local::unsafe_borrow(); let me: *mut Task = Local::unsafe_borrow();
(*me).death.collect_failure((*me).unwinder.result()); (*me).death.collect_failure((*me).unwinder.result());
// see comments on these statics for why they're used
if TASK_COUNT.fetch_sub(1, SeqCst) == 1 { if TASK_COUNT.fetch_sub(1, SeqCst) == 1 {
TASK_LOCK.lock(); TASK_LOCK.lock();
TASK_LOCK.signal(); TASK_LOCK.signal();
@ -386,6 +396,10 @@ impl Drop for Death {
} }
} }
/// The main function of all rust executables will by default use this function.
/// This function will *block* the OS thread (hence the `unsafe`) waiting for
/// all known tasks to complete. Once this function has returned, it is
/// guaranteed that no more user-defined code is still running.
pub unsafe fn wait_for_completion() { pub unsafe fn wait_for_completion() {
TASK_LOCK.lock(); TASK_LOCK.lock();
while TASK_COUNT.load(SeqCst) > 0 { while TASK_COUNT.load(SeqCst) > 0 {

View File

@ -32,7 +32,7 @@ use vec;
/// An atomically reference counted pointer. /// An atomically reference counted pointer.
/// ///
/// Enforces no shared-memory safety. /// Enforces no shared-memory safety.
#[unsafe_no_drop_flag] //#[unsafe_no_drop_flag] FIXME: #9758
pub struct UnsafeArc<T> { pub struct UnsafeArc<T> {
priv data: *mut ArcData<T>, priv data: *mut ArcData<T>,
} }

View File

@ -606,7 +606,6 @@ impl AstBuilder for @ExtCtxt {
~[ ~[
self.ident_of("std"), self.ident_of("std"),
self.ident_of("rt"), self.ident_of("rt"),
self.ident_of("task"),
self.ident_of("begin_unwind"), self.ident_of("begin_unwind"),
], ],
~[ ~[

View File

@ -1,20 +0,0 @@
// Copyright 2012 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.
// xfail-fast
// A simple test of starting the runtime manually
#[start]
fn start(argc: int, argv: **u8) -> int {
do std::rt::start(argc, argv) {
info!("creating my own runtime is joy");
}
}

View File

@ -1,17 +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 <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.
// xfail-fast
#[no_uv];
fn main() {
println!("hello");
}

View File

@ -1,26 +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 <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.
// xfail-fast make-check does not like `#[start]`
use std::rt;
#[start]
fn start(argc: int, argv: **u8) -> int {
do rt::start(argc, argv) {
println("First invocation");
};
do rt::start(argc, argv) {
println("Second invocation");
};
0
}

View File

@ -1,21 +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 <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.
// xfail-fast
#[start]
fn start(argc: int, argv: **u8) -> int {
do std::rt::start_on_main_thread(argc, argv) {
info!("running on main thread");
do spawn {
info!("running on another thread");
}
}
}

View File

@ -17,6 +17,5 @@ use std::task;
fn main() { fn main() {
let mut t = task::task(); let mut t = task::task();
t.sched_mode(task::SingleThreaded);
t.spawn(proc() ()); t.spawn(proc() ());
} }

View File

@ -10,6 +10,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// xfail-fast
#[allow(unused_imports)]; #[allow(unused_imports)];
#[no_std]; #[no_std];
@ -25,4 +27,5 @@ mod baz {
pub use x = std::str; pub use x = std::str;
} }
pub fn main() { } #[start]
pub fn start(_: int, _: **u8) -> int { 3 }