From 282f3d99a5ad85acbc58c03b5dfcdabf649c0c85 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 13 Dec 2013 21:14:08 -0800 Subject: [PATCH] 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". --- Makefile.in | 6 ++ mk/target.mk | 7 +- src/compiletest/compiletest.rs | 4 +- src/etc/licenseck.py | 6 +- src/libgreen/lib.rs | 22 +++++-- src/libnative/lib.rs | 2 + src/librustuv/homing.rs | 2 + src/librustuv/queue.rs | 2 + src/libstd/io/test.rs | 79 +++++++++++++++++++++++ src/libstd/rt/task.rs | 18 +++++- src/libstd/sync/arc.rs | 2 +- src/libsyntax/ext/build.rs | 1 - src/test/run-pass/core-rt-smoke.rs | 20 ------ src/test/run-pass/native-print-no-uv.rs | 17 ----- src/test/run-pass/rt-run-twice.rs | 26 -------- src/test/run-pass/rt-start-main-thread.rs | 21 ------ src/test/run-pass/spawning-with-debug.rs | 1 - src/test/run-pass/use.rs | 5 +- 18 files changed, 134 insertions(+), 107 deletions(-) delete mode 100644 src/test/run-pass/core-rt-smoke.rs delete mode 100644 src/test/run-pass/native-print-no-uv.rs delete mode 100644 src/test/run-pass/rt-run-twice.rs delete mode 100644 src/test/run-pass/rt-start-main-thread.rs diff --git a/Makefile.in b/Makefile.in index d5a62f11e05..f1b18e8f64b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 diff --git a/mk/target.mk b/mk/target.mk index 3746a4eafc0..db8488f792f 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -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 "$$@" diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 0fb75b7c8e0..89b6f06abfc 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -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"); } } diff --git a/src/etc/licenseck.py b/src/etc/licenseck.py index 78d0973fdfe..073322b0815 100644 --- a/src/etc/licenseck.py +++ b/src/etc/licenseck.py @@ -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): diff --git a/src/libgreen/lib.rs b/src/libgreen/lib.rs index bb219936ae0..57e2a0bfe16 100644 --- a/src/libgreen/lib.rs +++ b/src/libgreen/lib.rs @@ -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() diff --git a/src/libnative/lib.rs b/src/libnative/lib.rs index b97d9127277..44b66a7804d 100644 --- a/src/libnative/lib.rs +++ b/src/libnative/lib.rs @@ -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 diff --git a/src/librustuv/homing.rs b/src/librustuv/homing.rs index 1ee64398ca3..d7be06724a0 100644 --- a/src/librustuv/homing.rs +++ b/src/librustuv/homing.rs @@ -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}; diff --git a/src/librustuv/queue.rs b/src/librustuv/queue.rs index 22e7925b211..b36bdf62775 100644 --- a/src/librustuv/queue.rs +++ b/src/librustuv/queue.rs @@ -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; diff --git a/src/libstd/io/test.rs b/src/libstd/io/test.rs index dd24150e03e..e273aedf7cc 100644 --- a/src/libstd/io/test.rs +++ b/src/libstd/io/test.rs @@ -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() {} +} diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index 91e285b1061..c0e1086483d 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -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 { diff --git a/src/libstd/sync/arc.rs b/src/libstd/sync/arc.rs index 7b94a3acc2b..b405104c09a 100644 --- a/src/libstd/sync/arc.rs +++ b/src/libstd/sync/arc.rs @@ -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 { priv data: *mut ArcData, } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 930d25e7443..aa7e0d0eced 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -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"), ], ~[ diff --git a/src/test/run-pass/core-rt-smoke.rs b/src/test/run-pass/core-rt-smoke.rs deleted file mode 100644 index 6e3d9629da0..00000000000 --- a/src/test/run-pass/core-rt-smoke.rs +++ /dev/null @@ -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 or the MIT license -// , 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"); - } -} diff --git a/src/test/run-pass/native-print-no-uv.rs b/src/test/run-pass/native-print-no-uv.rs deleted file mode 100644 index d3b6d605984..00000000000 --- a/src/test/run-pass/native-print-no-uv.rs +++ /dev/null @@ -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 or the MIT license -// , 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"); -} diff --git a/src/test/run-pass/rt-run-twice.rs b/src/test/run-pass/rt-run-twice.rs deleted file mode 100644 index a9a26c2fbb1..00000000000 --- a/src/test/run-pass/rt-run-twice.rs +++ /dev/null @@ -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 or the MIT license -// , 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 -} diff --git a/src/test/run-pass/rt-start-main-thread.rs b/src/test/run-pass/rt-start-main-thread.rs deleted file mode 100644 index 47a723ce6e1..00000000000 --- a/src/test/run-pass/rt-start-main-thread.rs +++ /dev/null @@ -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 or the MIT license -// , 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"); - } - } -} diff --git a/src/test/run-pass/spawning-with-debug.rs b/src/test/run-pass/spawning-with-debug.rs index 76975d15c1d..f8094f9fdb9 100644 --- a/src/test/run-pass/spawning-with-debug.rs +++ b/src/test/run-pass/spawning-with-debug.rs @@ -17,6 +17,5 @@ use std::task; fn main() { let mut t = task::task(); - t.sched_mode(task::SingleThreaded); t.spawn(proc() ()); } diff --git a/src/test/run-pass/use.rs b/src/test/run-pass/use.rs index ddd4b10fd5c..56ce5397efb 100644 --- a/src/test/run-pass/use.rs +++ b/src/test/run-pass/use.rs @@ -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 }