]> git.proxmox.com Git - rustc.git/blob - src/libstd/rt/util.rs
04f36d99c8eb5155ccb8014cc28bc5451eff2267
[rustc.git] / src / libstd / rt / util.rs
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use io::prelude::*;
12
13 use env;
14 use fmt;
15 use intrinsics;
16 use libc::uintptr_t;
17 use sync::atomic::{self, Ordering};
18 use sys::stdio::Stderr;
19
20 /// Dynamically inquire about whether we're running under V.
21 /// You should usually not use this unless your test definitely
22 /// can't run correctly un-altered. Valgrind is there to help
23 /// you notice weirdness in normal, un-doctored code paths!
24 pub fn running_on_valgrind() -> bool {
25 extern {
26 fn rust_running_on_valgrind() -> uintptr_t;
27 }
28 unsafe { rust_running_on_valgrind() != 0 }
29 }
30
31 /// Valgrind has a fixed-sized array (size around 2000) of segment descriptors
32 /// wired into it; this is a hard limit and requires rebuilding valgrind if you
33 /// want to go beyond it. Normally this is not a problem, but in some tests, we
34 /// produce a lot of threads casually. Making lots of threads alone might not
35 /// be a problem _either_, except on OSX, the segments produced for new threads
36 /// _take a while_ to get reclaimed by the OS. Combined with the fact that libuv
37 /// schedulers fork off a separate thread for polling fsevents on OSX, we get a
38 /// perfect storm of creating "too many mappings" for valgrind to handle when
39 /// running certain stress tests in the runtime.
40 pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
41 (cfg!(target_os="macos")) && running_on_valgrind()
42 }
43
44 pub fn min_stack() -> usize {
45 static MIN: atomic::AtomicUsize = atomic::AtomicUsize::new(0);
46 match MIN.load(Ordering::SeqCst) {
47 0 => {}
48 n => return n - 1,
49 }
50 let amt = env::var("RUST_MIN_STACK").ok().and_then(|s| s.parse().ok());
51 let amt = amt.unwrap_or(2 * 1024 * 1024);
52 // 0 is our sentinel value, so ensure that we'll never see 0 after
53 // initialization has run
54 MIN.store(amt + 1, Ordering::SeqCst);
55 return amt;
56 }
57
58 // Indicates whether we should perform expensive sanity checks, including rtassert!
59 //
60 // FIXME: Once the runtime matures remove the `true` below to turn off rtassert,
61 // etc.
62 pub const ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) ||
63 cfg!(rtassert);
64
65 pub fn dumb_print(args: fmt::Arguments) {
66 let _ = Stderr::new().map(|mut stderr| stderr.write_fmt(args));
67 }
68
69 pub fn abort(args: fmt::Arguments) -> ! {
70 rterrln!("fatal runtime error: {}", args);
71 unsafe { intrinsics::abort(); }
72 }
73
74 pub unsafe fn report_overflow() {
75 use thread;
76 rterrln!("\nthread '{}' has overflowed its stack",
77 thread::current().name().unwrap_or("<unknown>"));
78 }