about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/compiletest/runtest.rs13
-rw-r--r--src/libstd/rt/comm.rs10
-rw-r--r--src/libstd/rt/sched.rs2
-rw-r--r--src/libstd/rt/test.rs14
-rw-r--r--src/libstd/rt/util.rs28
-rw-r--r--src/libstd/run.rs10
-rw-r--r--src/libstd/unstable/mod.rs15
-rw-r--r--src/test/auxiliary/xc_conditions.rs19
-rw-r--r--src/test/auxiliary/xc_conditions_2.rs15
-rw-r--r--src/test/auxiliary/xc_conditions_3.rs21
-rw-r--r--src/test/auxiliary/xc_conditions_4.rs29
-rw-r--r--src/test/run-pass/foreign-struct.rs1
-rw-r--r--src/test/run-pass/issue-4929.rs12
-rw-r--r--src/test/run-pass/xc_conditions_client.rs40
-rw-r--r--src/test/run-pass/xc_conditions_client_2.rs21
-rw-r--r--src/test/run-pass/xc_conditions_client_3.rs38
-rw-r--r--src/test/run-pass/xc_conditions_client_4.rs32
17 files changed, 303 insertions, 17 deletions
diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs
index 2346aba3bcb..a31efe26c1a 100644
--- a/src/compiletest/runtest.rs
+++ b/src/compiletest/runtest.rs
@@ -26,6 +26,7 @@ use std::os;
 use std::str;
 use std::task::{spawn_sched, SingleThreaded};
 use std::vec;
+use std::unstable::running_on_valgrind;
 
 use extra::test::MetricMap;
 
@@ -38,11 +39,21 @@ pub fn run(config: config, testfile: ~str) {
     // that destroys parallelism if we let normal schedulers block.
     // It should be possible to remove this spawn once std::run is
     // rewritten to be non-blocking.
-    do spawn_sched(SingleThreaded) {
+    //
+    // We do _not_ create another thread if we're running on V because
+    // it serializes all threads anyways.
+    if running_on_valgrind() {
         let config = config.take();
         let testfile = testfile.take();
         let mut _mm = MetricMap::new();
         run_metrics(config, testfile, &mut _mm);
+    } else {
+        do spawn_sched(SingleThreaded) {
+            let config = config.take();
+            let testfile = testfile.take();
+            let mut _mm = MetricMap::new();
+            run_metrics(config, testfile, &mut _mm);
+        }
     }
 }
 
diff --git a/src/libstd/rt/comm.rs b/src/libstd/rt/comm.rs
index 42d59ccdf95..49cf8c239b7 100644
--- a/src/libstd/rt/comm.rs
+++ b/src/libstd/rt/comm.rs
@@ -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() {
@@ -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>();
@@ -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>();
@@ -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>();
@@ -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>();
@@ -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>();
@@ -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);
@@ -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::<()>();
@@ -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);
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs
index ce4e64c47d2..e65a45f0e07 100644
--- a/src/libstd/rt/sched.rs
+++ b/src/libstd/rt/sched.rs
@@ -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]
@@ -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();
diff --git a/src/libstd/rt/test.rs b/src/libstd/rt/test.rs
index a9331157749..4e2f9fbe130 100644
--- a/src/libstd/rt/test.rs
+++ b/src/libstd/rt/test.rs
@@ -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;
@@ -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
+                }
             }
         };
 
diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs
index b8c7c8761e8..c81f3ec9a79 100644
--- a/src/libstd/rt/util.rs
+++ b/src/libstd/rt/util.rs
@@ -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)];
@@ -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()
+            }
+        }
     }
 }
 
diff --git a/src/libstd/run.rs b/src/libstd/run.rs
index a43d448dae5..eeaee4c14a5 100644
--- a/src/libstd/run.rs
+++ b/src/libstd/run.rs
@@ -955,6 +955,7 @@ mod tests {
     use path::Path;
     use run;
     use str;
+    use unstable::running_on_valgrind;
 
     #[test]
     #[cfg(windows)]
@@ -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;
-    }
 }
diff --git a/src/libstd/unstable/mod.rs b/src/libstd/unstable/mod.rs
index 6ad15bfc7c0..51de3caf2ae 100644
--- a/src/libstd/unstable/mod.rs
+++ b/src/libstd/unstable/mod.rs
@@ -14,6 +14,7 @@ use comm::{GenericChan, GenericPort};
 use comm;
 use prelude::*;
 use task;
+use libc::uintptr_t;
 
 pub mod dynamic_lib;
 
@@ -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;
+}
diff --git a/src/test/auxiliary/xc_conditions.rs b/src/test/auxiliary/xc_conditions.rs
new file mode 100644
index 00000000000..927602de169
--- /dev/null
+++ b/src/test/auxiliary/xc_conditions.rs
@@ -0,0 +1,19 @@
+// 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.
+
+#[crate_type="lib"];
+
+condition! {
+    pub oops: int -> int;
+}
+
+pub fn trouble() -> int {
+    oops::cond.raise(1)
+}
diff --git a/src/test/auxiliary/xc_conditions_2.rs b/src/test/auxiliary/xc_conditions_2.rs
new file mode 100644
index 00000000000..16a5bb56343
--- /dev/null
+++ b/src/test/auxiliary/xc_conditions_2.rs
@@ -0,0 +1,15 @@
+// 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.
+
+#[crate_type="lib"];
+
+condition! {
+    pub oops: int -> int;
+}
diff --git a/src/test/auxiliary/xc_conditions_3.rs b/src/test/auxiliary/xc_conditions_3.rs
new file mode 100644
index 00000000000..d5ce63e7e9b
--- /dev/null
+++ b/src/test/auxiliary/xc_conditions_3.rs
@@ -0,0 +1,21 @@
+// 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.
+
+#[crate_type="lib"];
+
+condition! {
+    pub oops: int -> int;
+}
+
+pub fn guard(k: extern fn() -> int, x: int) -> int {
+    do oops::cond.trap(|i| i*x).inside {
+        k()
+    }
+}
diff --git a/src/test/auxiliary/xc_conditions_4.rs b/src/test/auxiliary/xc_conditions_4.rs
new file mode 100644
index 00000000000..c9b5a1dc2b8
--- /dev/null
+++ b/src/test/auxiliary/xc_conditions_4.rs
@@ -0,0 +1,29 @@
+// 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.
+
+#[crate_type="lib"];
+
+#[deriving(Eq)]
+pub enum Color {
+    Red, Green, Blue
+}
+
+condition! {
+    pub oops: (int,float,~str) -> ::Color;
+}
+
+pub trait Thunk<T> {
+    fn call(self) -> T;
+}
+
+pub fn callback<T,TH:Thunk<T>>(t:TH) -> T {
+    t.call()
+}
+
diff --git a/src/test/run-pass/foreign-struct.rs b/src/test/run-pass/foreign-struct.rs
index 57686b200f2..a70fec92659 100644
--- a/src/test/run-pass/foreign-struct.rs
+++ b/src/test/run-pass/foreign-struct.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// xfail-win32
 // Passing enums by value
 
 pub enum void { }
diff --git a/src/test/run-pass/issue-4929.rs b/src/test/run-pass/issue-4929.rs
new file mode 100644
index 00000000000..5803c3da6cc
--- /dev/null
+++ b/src/test/run-pass/issue-4929.rs
@@ -0,0 +1,12 @@
+// 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.
+
+fn make_adder(x: int) -> @fn(int) -> int { |y| x + y }
+pub fn main() { }
diff --git a/src/test/run-pass/xc_conditions_client.rs b/src/test/run-pass/xc_conditions_client.rs
new file mode 100644
index 00000000000..ffef5369f23
--- /dev/null
+++ b/src/test/run-pass/xc_conditions_client.rs
@@ -0,0 +1,40 @@
+// 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
+// aux-build:xc_conditions.rs
+
+extern mod xc_conditions;
+use xc_conditions::oops;
+use xc_conditions::trouble;
+
+// Tests of cross-crate conditions; the condition is
+// defined in lib, and we test various combinations
+// of `trap` and `raise` in the client or the lib where
+// the condition was defined. Also in test #4 we use
+// more complex features (generics, traits) in
+// combination with the condition.
+//
+//                    trap   raise
+//                    ------------
+// xc_conditions  :   client   lib
+// xc_conditions_2:   client   client
+// xc_conditions_3:   lib      client
+// xc_conditions_4:   client   client  (with traits)
+//
+// the trap=lib, raise=lib case isn't tested since
+// there's no cross-crate-ness to test in that case.
+
+pub fn main() {
+    do oops::cond.trap(|_i| 12345).inside {
+        let x = trouble();
+        assert_eq!(x,12345);
+    }
+}
\ No newline at end of file
diff --git a/src/test/run-pass/xc_conditions_client_2.rs b/src/test/run-pass/xc_conditions_client_2.rs
new file mode 100644
index 00000000000..9666c037449
--- /dev/null
+++ b/src/test/run-pass/xc_conditions_client_2.rs
@@ -0,0 +1,21 @@
+// 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
+// aux-build:xc_conditions_2.rs
+
+extern mod xc_conditions_2;
+use xcc = xc_conditions_2;
+
+pub fn main() {
+    do xcc::oops::cond.trap(|_| 1).inside {
+        xcc::oops::cond.raise(1);
+    }
+}
diff --git a/src/test/run-pass/xc_conditions_client_3.rs b/src/test/run-pass/xc_conditions_client_3.rs
new file mode 100644
index 00000000000..7d16572c139
--- /dev/null
+++ b/src/test/run-pass/xc_conditions_client_3.rs
@@ -0,0 +1,38 @@
+// 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
+// aux-build:xc_conditions_3.rs
+
+extern mod xc_conditions_3;
+use xcc = xc_conditions_3;
+
+pub fn main() {
+    assert_eq!(xcc::guard(a, 1), 40);
+}
+
+pub fn a() -> int {
+    assert_eq!(xcc::oops::cond.raise(7), 7);
+    xcc::guard(b, 2)
+}
+
+pub fn b() -> int {
+    assert_eq!(xcc::oops::cond.raise(8), 16);
+    xcc::guard(c, 3)
+}
+
+pub fn c() -> int {
+    assert_eq!(xcc::oops::cond.raise(9), 27);
+    xcc::guard(d, 4)
+}
+
+pub fn d() -> int {
+    xcc::oops::cond.raise(10)
+}
diff --git a/src/test/run-pass/xc_conditions_client_4.rs b/src/test/run-pass/xc_conditions_client_4.rs
new file mode 100644
index 00000000000..9a4a8683742
--- /dev/null
+++ b/src/test/run-pass/xc_conditions_client_4.rs
@@ -0,0 +1,32 @@
+// 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
+// aux-build:xc_conditions_4.rs
+
+extern mod xc_conditions_4;
+use xcc = xc_conditions_4;
+
+struct SThunk {
+    x: int
+}
+
+impl xcc::Thunk<xcc::Color> for SThunk {
+    fn call(self) -> xcc::Color {
+        xcc::oops::cond.raise((self.x, 1.23, ~"oh no"))
+    }
+}
+
+pub fn main() {
+    do xcc::oops::cond.trap(|_| xcc::Red).inside {
+        let t = SThunk { x : 10 };
+        assert_eq!(xcc::callback(t), xcc::Red)
+    }
+}
\ No newline at end of file