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
# Same interface as above, but deletes rather than just listing the files.
ifdef VERBOSE
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
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
# 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_RGLOB_$(2)),$$(notdir $$@))
# NOTE: after the next snapshot remove these '-L' flags
$$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X_$(3)): \
$$(DRIVER_CRATE) \
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
$$(SREQ$(1)_T_$(2)_H_$(3)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(3)) \
| $$(TBIN$(1)_T_$(2)_H_$(3))/
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(2)_H_$(3)) --cfg rustc -o $$@ $$< \
-L $$(UV_SUPPORT_DIR_$(2)) \
-L $$(dir $$(LIBUV_LIB_$(2)))
$$(STAGE$(1)_T_$(2)_H_$(3)) --cfg rustc -o $$@ $$<
ifdef CFG_ENABLE_PAX_FLAGS
@$$(call E, apply PaX flags: $$@)
@"$(CFG_PAXCTL)" -cm "$$@"

View File

@ -16,7 +16,7 @@
extern mod extra;
use std::os;
use std::rt;
use std::io;
use std::io::fs;
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
// parallel (especially when we have lots and lots of child processes).
// For context, see #8904
rt::test::prepare_for_lots_of_tests();
io::test::raise_fd_limit();
let res = test::run_tests_console(&opts, tests);
if !res { fail!("Some tests failed"); }
}

View File

@ -76,9 +76,9 @@ exceptions = [
"rt/isaac/randport.cpp", # public domain
"rt/isaac/rand.h", # public domain
"rt/isaac/standard.h", # public domain
"libstd/rt/mpsc_queue.rs", # BSD
"libstd/rt/spsc_queue.rs", # BSD
"libstd/rt/mpmc_bounded_queue.rs", # BSD
"libstd/sync/mpsc_queue.rs", # BSD
"libstd/sync/spsc_queue.rs", # BSD
"libstd/sync/mpmc_bounded_queue.rs", # BSD
]
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
//! functionality inside of 1:1 programs.
#[pkgid = "green#0.9-pre"];
#[link(name = "green",
package_id = "green",
vers = "0.9-pre",
@ -30,17 +31,16 @@
// NB this does *not* include globs, please keep it that way.
#[feature(macro_rules)];
use std::cast;
use std::os;
use std::rt::thread::Thread;
use std::rt;
use std::rt::crate_map;
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::deque;
use std::task::TaskOpts;
use std::vec;
use std::util;
use std::vec;
use stdtask = std::rt::task;
use sched::{Shutdown, Scheduler, SchedHandle, TaskFromFriend, NewNeighbor};
@ -58,9 +58,9 @@ pub mod sleeper_list;
pub mod stack;
pub mod task;
#[cfg(stage0)]
#[lang = "start"]
pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
use std::cast;
do start(argc, argv) {
let main: extern "Rust" fn() = unsafe { cast::transmute(main) };
main();
@ -103,7 +103,15 @@ pub fn start(argc: int, argv: **u8, main: proc()) -> int {
/// have returned.
pub fn run(main: proc()) -> int {
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(); }
pool.shutdown();
os::get_exit_status()

View File

@ -14,6 +14,7 @@
//! runtime. In addition, all I/O provided by this crate is the thread blocking
//! version of I/O.
#[pkgid = "native#0.9-pre"];
#[link(name = "native",
package_id = "native",
vers = "0.9-pre",
@ -24,6 +25,7 @@
#[crate_type = "rlib"];
#[crate_type = "dylib"];
// Allow check-stage0-native for now
#[cfg(stage0, test)] extern mod green;
// 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
//! signalling is achieved with an async handle.
#[allow(dead_code)];
use std::rt::local::Local;
use std::rt::rtio::LocalIo;
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
//! async handle is active or not.
#[allow(dead_code)];
use std::cast;
use std::libc::{c_void, c_int};
use std::rt::task::BlockedTask;

View File

@ -113,3 +113,82 @@ fn base_port() -> u16 {
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::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_LOCK: Mutex = MUTEX_INIT;
@ -181,10 +186,15 @@ impl Task {
// Cleanup the dynamic borrowck debugging info
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 {
let me: *mut Task = Local::unsafe_borrow();
(*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 {
TASK_LOCK.lock();
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() {
TASK_LOCK.lock();
while TASK_COUNT.load(SeqCst) > 0 {

View File

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

View File

@ -606,7 +606,6 @@ impl AstBuilder for @ExtCtxt {
~[
self.ident_of("std"),
self.ident_of("rt"),
self.ident_of("task"),
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() {
let mut t = task::task();
t.sched_mode(task::SingleThreaded);
t.spawn(proc() ());
}

View File

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