Skip to content

Commit 1b84e34

Browse files
committed
Merge branch 'mac-valgrind-thread-fixes' of https://github.com/graydon/rust into rollup
2 parents 25886e5 + 98dc7b1 commit 1b84e34

File tree

6 files changed

+61
-14
lines changed

6 files changed

+61
-14
lines changed

src/libstd/rt/comm.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,7 @@ mod test {
714714
use rt::test::*;
715715
use cell::Cell;
716716
use iter::Times;
717+
use rt::util;
717718

718719
#[test]
719720
fn oneshot_single_thread_close_port_first() {
@@ -862,6 +863,7 @@ mod test {
862863

863864
#[test]
864865
fn oneshot_multi_thread_close_stress() {
866+
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
865867
do stress_factor().times {
866868
do run_in_newsched_task {
867869
let (port, chan) = oneshot::<int>();
@@ -877,6 +879,7 @@ mod test {
877879

878880
#[test]
879881
fn oneshot_multi_thread_send_close_stress() {
882+
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
880883
do stress_factor().times {
881884
do run_in_newsched_task {
882885
let (port, chan) = oneshot::<int>();
@@ -897,6 +900,7 @@ mod test {
897900

898901
#[test]
899902
fn oneshot_multi_thread_recv_close_stress() {
903+
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
900904
do stress_factor().times {
901905
do run_in_newsched_task {
902906
let (port, chan) = oneshot::<int>();
@@ -923,6 +927,7 @@ mod test {
923927

924928
#[test]
925929
fn oneshot_multi_thread_send_recv_stress() {
930+
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
926931
do stress_factor().times {
927932
do run_in_newsched_task {
928933
let (port, chan) = oneshot::<~int>();
@@ -942,6 +947,7 @@ mod test {
942947

943948
#[test]
944949
fn stream_send_recv_stress() {
950+
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
945951
do stress_factor().times {
946952
do run_in_mt_newsched_task {
947953
let (port, chan) = stream::<~int>();
@@ -986,6 +992,7 @@ mod test {
986992

987993
#[test]
988994
fn shared_chan_stress() {
995+
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
989996
do run_in_mt_newsched_task {
990997
let (port, chan) = stream();
991998
let chan = SharedChan::new(chan);
@@ -1005,6 +1012,7 @@ mod test {
10051012

10061013
#[test]
10071014
fn shared_port_stress() {
1015+
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
10081016
do run_in_mt_newsched_task {
10091017
// XXX: Removing these type annotations causes an ICE
10101018
let (end_port, end_chan) = stream::<()>();
@@ -1085,6 +1093,8 @@ mod test {
10851093
use rand;
10861094
use rand::RngUtil;
10871095

1096+
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
1097+
10881098
do run_in_mt_newsched_task {
10891099
let (end_port, end_chan) = stream::<()>();
10901100
let end_chan = SharedChan::new(end_chan);

src/libstd/rt/sched.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,7 @@ mod test {
819819
use cell::Cell;
820820
use rt::thread::Thread;
821821
use rt::task::{Task, Sched};
822+
use rt::util;
822823
use option::{Some};
823824

824825
#[test]
@@ -1040,6 +1041,7 @@ mod test {
10401041

10411042
#[test]
10421043
fn test_stress_schedule_task_states() {
1044+
if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
10431045
let n = stress_factor() * 120;
10441046
for _ in range(0, n as int) {
10451047
test_schedule_home_states();

src/libstd/rt/test.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use iterator::{Iterator, range};
1818
use super::io::net::ip::{SocketAddr, Ipv4Addr, Ipv6Addr};
1919
use vec::{OwnedVector, MutableVector, ImmutableVector};
2020
use rt::sched::Scheduler;
21-
use unstable::run_in_bare_thread;
21+
use unstable::{run_in_bare_thread};
2222
use rt::thread::Thread;
2323
use rt::task::Task;
2424
use rt::uv::uvio::UvEventLoop;
@@ -160,10 +160,14 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
160160
let nthreads = match os::getenv("RUST_RT_TEST_THREADS") {
161161
Some(nstr) => FromStr::from_str(nstr).unwrap(),
162162
None => {
163-
// Using more threads than cores in test code
164-
// to force the OS to preempt them frequently.
165-
// Assuming that this help stress test concurrent types.
166-
util::num_cpus() * 2
163+
if util::limit_thread_creation_due_to_osx_and_valgrind() {
164+
1
165+
} else {
166+
// Using more threads than cores in test code
167+
// to force the OS to preempt them frequently.
168+
// Assuming that this help stress test concurrent types.
169+
util::num_cpus() * 2
170+
}
167171
}
168172
};
169173

src/libstd/rt/util.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use libc;
1414
use option::{Some, None};
1515
use os;
1616
use str::StrSlice;
17+
use unstable::running_on_valgrind;
1718

1819
/// Get the number of cores available
1920
pub fn num_cpus() -> uint {
@@ -26,12 +27,35 @@ pub fn num_cpus() -> uint {
2627
}
2728
}
2829

30+
/// Valgrind has a fixed-sized array (size around 2000) of segment descriptors wired into it; this
31+
/// is a hard limit and requires rebuilding valgrind if you want to go beyond it. Normally this is
32+
/// not a problem, but in some tests, we produce a lot of threads casually. Making lots of threads
33+
/// alone might not be a problem _either_, except on OSX, the segments produced for new threads
34+
/// _take a while_ to get reclaimed by the OS. Combined with the fact that libuv schedulers fork off
35+
/// a separate thread for polling fsevents on OSX, we get a perfect storm of creating "too many
36+
/// mappings" for valgrind to handle when running certain stress tests in the runtime.
37+
#[cfg(target_os="macos")]
38+
pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
39+
running_on_valgrind()
40+
}
41+
42+
#[cfg(not(target_os="macos"))]
43+
pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
44+
false
45+
}
46+
2947
/// Get's the number of scheduler threads requested by the environment
3048
/// either `RUST_THREADS` or `num_cpus`.
3149
pub fn default_sched_threads() -> uint {
3250
match os::getenv("RUST_THREADS") {
3351
Some(nstr) => FromStr::from_str(nstr).unwrap(),
34-
None => num_cpus()
52+
None => {
53+
if limit_thread_creation_due_to_osx_and_valgrind() {
54+
1
55+
} else {
56+
num_cpus()
57+
}
58+
}
3559
}
3660
}
3761

src/libstd/run.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,7 @@ mod tests {
941941
use path::Path;
942942
use run;
943943
use str;
944+
use unstable::running_on_valgrind;
944945

945946
#[test]
946947
#[cfg(windows)]
@@ -1349,12 +1350,4 @@ mod tests {
13491350
13501351
assert!(output.contains("RUN_TEST_NEW_ENV=123"));
13511352
}
1352-
1353-
fn running_on_valgrind() -> bool {
1354-
unsafe { rust_running_on_valgrind() != 0 }
1355-
}
1356-
1357-
extern {
1358-
fn rust_running_on_valgrind() -> uintptr_t;
1359-
}
13601353
}

src/libstd/unstable/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use comm::{GenericChan, GenericPort};
1414
use comm;
1515
use prelude::*;
1616
use task;
17+
use libc::uintptr_t;
1718

1819
pub mod dynamic_lib;
1920

@@ -116,3 +117,16 @@ pub fn change_dir_locked(p: &Path, action: &fn()) -> bool {
116117
fn rust_drop_change_dir_lock();
117118
}
118119
}
120+
121+
122+
/// Dynamically inquire about whether we're running under V.
123+
/// You should usually not use this unless your test definitely
124+
/// can't run correctly un-altered. Valgrind is there to help
125+
/// you notice weirdness in normal, un-doctored code paths!
126+
pub fn running_on_valgrind() -> bool {
127+
unsafe { rust_running_on_valgrind() != 0 }
128+
}
129+
130+
extern {
131+
fn rust_running_on_valgrind() -> uintptr_t;
132+
}

0 commit comments

Comments
 (0)