Skip to content

Commit

Permalink
Try to fix mac valgrind bot by disabling thread-heavy activities.
Browse files Browse the repository at this point in the history
  • Loading branch information
graydon committed Aug 19, 2013
1 parent 29a449a commit 19f4ae1
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 15 deletions.
10 changes: 10 additions & 0 deletions src/libstd/rt/comm.rs
Expand Up @@ -727,6 +727,7 @@ mod test {
use rt::test::*;
use cell::Cell;
use iter::Times;
use rt::util;

#[test]
fn oneshot_single_thread_close_port_first() {
Expand Down Expand Up @@ -875,6 +876,7 @@ mod test {

#[test]
fn oneshot_multi_thread_close_stress() {
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
do stress_factor().times {
do run_in_newsched_task {
let (port, chan) = oneshot::<int>();
Expand All @@ -890,6 +892,7 @@ mod test {

#[test]
fn oneshot_multi_thread_send_close_stress() {
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
do stress_factor().times {
do run_in_newsched_task {
let (port, chan) = oneshot::<int>();
Expand All @@ -910,6 +913,7 @@ mod test {

#[test]
fn oneshot_multi_thread_recv_close_stress() {
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
do stress_factor().times {
do run_in_newsched_task {
let (port, chan) = oneshot::<int>();
Expand All @@ -936,6 +940,7 @@ mod test {

#[test]
fn oneshot_multi_thread_send_recv_stress() {
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
do stress_factor().times {
do run_in_newsched_task {
let (port, chan) = oneshot::<~int>();
Expand All @@ -955,6 +960,7 @@ mod test {

#[test]
fn stream_send_recv_stress() {
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
do stress_factor().times {
do run_in_mt_newsched_task {
let (port, chan) = stream::<~int>();
Expand Down Expand Up @@ -999,6 +1005,7 @@ mod test {

#[test]
fn shared_chan_stress() {
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
do run_in_mt_newsched_task {
let (port, chan) = stream();
let chan = SharedChan::new(chan);
Expand All @@ -1018,6 +1025,7 @@ mod test {

#[test]
fn shared_port_stress() {
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
do run_in_mt_newsched_task {
// XXX: Removing these type annotations causes an ICE
let (end_port, end_chan) = stream::<()>();
Expand Down Expand Up @@ -1098,6 +1106,8 @@ mod test {
use rand;
use rand::RngUtil;

if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }

do run_in_mt_newsched_task {
let (end_port, end_chan) = stream::<()>();
let end_chan = SharedChan::new(end_chan);
Expand Down
2 changes: 2 additions & 0 deletions src/libstd/rt/sched.rs
Expand Up @@ -819,6 +819,7 @@ mod test {
use cell::Cell;
use rt::thread::Thread;
use rt::task::{Task, Sched};
use rt::util;
use option::{Some};

#[test]
Expand Down Expand Up @@ -1040,6 +1041,7 @@ mod test {

#[test]
fn test_stress_schedule_task_states() {
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
let n = stress_factor() * 120;
for _ in range(0, n as int) {
test_schedule_home_states();
Expand Down
14 changes: 9 additions & 5 deletions src/libstd/rt/test.rs
Expand Up @@ -18,7 +18,7 @@ use iterator::{Iterator, range};
use super::io::net::ip::{SocketAddr, Ipv4Addr, Ipv6Addr};
use vec::{OwnedVector, MutableVector, ImmutableVector};
use rt::sched::Scheduler;
use unstable::run_in_bare_thread;
use unstable::{run_in_bare_thread};
use rt::thread::Thread;
use rt::task::Task;
use rt::uv::uvio::UvEventLoop;
Expand Down Expand Up @@ -162,10 +162,14 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
let nthreads = match os::getenv("RUST_RT_TEST_THREADS") {
Some(nstr) => FromStr::from_str(nstr).unwrap(),
None => {
// Using more threads than cores in test code
// to force the OS to preempt them frequently.
// Assuming that this help stress test concurrent types.
util::num_cpus() * 2
if util::limit_thread_creation_due_to_osx_and_valgrind() {
1
} else {
// Using more threads than cores in test code
// to force the OS to preempt them frequently.
// Assuming that this help stress test concurrent types.
util::num_cpus() * 2
}
}
};

Expand Down
28 changes: 27 additions & 1 deletion src/libstd/rt/util.rs
Expand Up @@ -15,6 +15,9 @@ use option::{Some, None};
use os;
use str::StrSlice;

#[cfg(target_os="macos")]
use unstable::running_on_valgrind;

/// Get the number of cores available
pub fn num_cpus() -> uint {
#[fixed_stack_segment]; #[inline(never)];
Expand All @@ -28,12 +31,35 @@ pub fn num_cpus() -> uint {
}
}

/// Valgrind has a fixed-sized array (size around 2000) of segment descriptors wired into it; this
/// is a hard limit and requires rebuilding valgrind if you want to go beyond it. Normally this is
/// not a problem, but in some tests, we produce a lot of threads casually. Making lots of threads
/// alone might not be a problem _either_, except on OSX, the segments produced for new threads
/// _take a while_ to get reclaimed by the OS. Combined with the fact that libuv schedulers fork off
/// a separate thread for polling fsevents on OSX, we get a perfect storm of creating "too many
/// mappings" for valgrind to handle when running certain stress tests in the runtime.
#[cfg(target_os="macos")]
pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
running_on_valgrind()
}

#[cfg(not(target_os="macos"))]
pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
false
}

/// Get's the number of scheduler threads requested by the environment
/// either `RUST_THREADS` or `num_cpus`.
pub fn default_sched_threads() -> uint {
match os::getenv("RUST_THREADS") {
Some(nstr) => FromStr::from_str(nstr).unwrap(),
None => num_cpus()
None => {
if limit_thread_creation_due_to_osx_and_valgrind() {
1
} else {
num_cpus()
}
}
}
}

Expand Down
10 changes: 1 addition & 9 deletions src/libstd/run.rs
Expand Up @@ -955,6 +955,7 @@ mod tests {
use path::Path;
use run;
use str;
use unstable::running_on_valgrind;

#[test]
#[cfg(windows)]
Expand Down Expand Up @@ -1365,13 +1366,4 @@ mod tests {

assert!(output.contains("RUN_TEST_NEW_ENV=123"));
}

fn running_on_valgrind() -> bool {
#[fixed_stack_segment]; #[inline(never)];
unsafe { rust_running_on_valgrind() != 0 }
}

extern {
fn rust_running_on_valgrind() -> uintptr_t;
}
}
15 changes: 15 additions & 0 deletions src/libstd/unstable/mod.rs
Expand Up @@ -14,6 +14,7 @@ use comm::{GenericChan, GenericPort};
use comm;
use prelude::*;
use task;
use libc::uintptr_t;

pub mod dynamic_lib;

Expand Down Expand Up @@ -118,3 +119,17 @@ pub fn change_dir_locked(p: &Path, action: &fn()) -> bool {
fn rust_drop_change_dir_lock();
}
}


/// Dynamically inquire about whether we're running under V.
/// You should usually not use this unless your test definitely
/// can't run correctly un-altered. Valgrind is there to help
/// you notice weirdness in normal, un-doctored code paths!
pub fn running_on_valgrind() -> bool {
#[fixed_stack_segment]; #[inline(never)];
unsafe { rust_running_on_valgrind() != 0 }
}

extern {
fn rust_running_on_valgrind() -> uintptr_t;
}

0 comments on commit 19f4ae1

Please sign in to comment.