Skip to content

Commit 544643f

Browse files
committed
---
yaml --- r: 65023 b: refs/heads/snap-stage3 c: 34101d2 h: refs/heads/master i: 65021: bae03f3 65019: cad6fcf 65015: 6590576 65007: 09ee8a9 64991: e11e77e 64959: f4843b8 64895: 1479eb7 64767: 6b3415b 64511: 73dd451 v: v3
1 parent 809c547 commit 544643f

File tree

2 files changed

+84
-5
lines changed

2 files changed

+84
-5
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 2d28d645422c1617be58c8ca7ad9a457264ca850
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 6be014d23c178a69a5ce4b709cb3497a1e81a412
4+
refs/heads/snap-stage3: 34101d2320583a0a95ab3afc4c2b6b75dadb5cd7
55
refs/heads/try: 7b78b52e602bb3ea8174f9b2006bff3315f03ef9
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/libstd/rt/test.rs

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,24 +63,103 @@ pub fn run_in_newsched_task_core(f: ~fn()) {
6363
sched.bootstrap(task);
6464
}
6565

66+
#[cfg(target_os="macos")]
67+
#[allow(non_camel_case_types)]
68+
mod darwin_fd_limit {
69+
/*!
70+
* darwin_fd_limit exists to work around an issue where launchctl on Mac OS X defaults the
71+
* rlimit maxfiles to 256/unlimited. The default soft limit of 256 ends up being far too low
72+
* for our multithreaded scheduler testing, depending on the number of cores available.
73+
*
74+
* This fixes issue #7772.
75+
*/
76+
77+
use libc;
78+
type rlim_t = libc::uint64_t;
79+
struct rlimit {
80+
rlim_cur: rlim_t,
81+
rlim_max: rlim_t
82+
}
83+
#[nolink]
84+
extern {
85+
// name probably doesn't need to be mut, but the C function doesn't specify const
86+
fn sysctl(name: *mut libc::c_int, namelen: libc::c_uint,
87+
oldp: *mut libc::c_void, oldlenp: *mut libc::size_t,
88+
newp: *mut libc::c_void, newlen: libc::size_t) -> libc::c_int;
89+
fn getrlimit(resource: libc::c_int, rlp: *mut rlimit) -> libc::c_int;
90+
fn setrlimit(resource: libc::c_int, rlp: *rlimit) -> libc::c_int;
91+
}
92+
static CTL_KERN: libc::c_int = 1;
93+
static KERN_MAXFILESPERPROC: libc::c_int = 29;
94+
static RLIMIT_NOFILE: libc::c_int = 8;
95+
96+
pub unsafe fn raise_fd_limit() {
97+
// The strategy here is to fetch the current resource limits, read the kern.maxfilesperproc
98+
// sysctl value, and bump the soft resource limit for maxfiles up to the sysctl value.
99+
use ptr::{to_unsafe_ptr, to_mut_unsafe_ptr, mut_null};
100+
use sys::size_of_val;
101+
use os::last_os_error;
102+
103+
// Fetch the kern.maxfilesperproc value
104+
let mut mib: [libc::c_int, ..2] = [CTL_KERN, KERN_MAXFILESPERPROC];
105+
let mut maxfiles: libc::c_int = 0;
106+
let mut size: libc::size_t = size_of_val(&maxfiles) as libc::size_t;
107+
if sysctl(to_mut_unsafe_ptr(&mut mib[0]), 2,
108+
to_mut_unsafe_ptr(&mut maxfiles) as *mut libc::c_void,
109+
to_mut_unsafe_ptr(&mut size),
110+
mut_null(), 0) != 0 {
111+
let err = last_os_error();
112+
error!("raise_fd_limit: error calling sysctl: %s", err);
113+
return;
114+
}
115+
116+
// Fetch the current resource limits
117+
let mut rlim = rlimit{rlim_cur: 0, rlim_max: 0};
118+
if getrlimit(RLIMIT_NOFILE, to_mut_unsafe_ptr(&mut rlim)) != 0 {
119+
let err = last_os_error();
120+
error!("raise_fd_limit: error calling getrlimit: %s", err);
121+
return;
122+
}
123+
124+
// Bump the soft limit to the smaller of kern.maxfilesperproc and the hard limit
125+
rlim.rlim_cur = ::cmp::min(maxfiles as rlim_t, rlim.rlim_max);
126+
127+
// Set our newly-increased resource limit
128+
if setrlimit(RLIMIT_NOFILE, to_unsafe_ptr(&rlim)) != 0 {
129+
let err = last_os_error();
130+
error!("raise_fd_limit: error calling setrlimit: %s", err);
131+
return;
132+
}
133+
}
134+
}
135+
136+
#[cfg(not(target_os="macos"))]
137+
mod darwin_fd_limit {
138+
pub unsafe fn raise_fd_limit() {}
139+
}
140+
66141
/// Create more than one scheduler and run a function in a task
67142
/// in one of the schedulers. The schedulers will stay alive
68143
/// until the function `f` returns.
69144
pub fn run_in_mt_newsched_task(f: ~fn()) {
70145
use os;
71146
use from_str::FromStr;
72147
use rt::sched::Shutdown;
148+
use rt::util;
149+
150+
// Bump the fd limit on OS X. See darwin_fd_limit for an explanation.
151+
unsafe { darwin_fd_limit::raise_fd_limit() }
73152

74153
let f = Cell::new(f);
75154

76155
do run_in_bare_thread {
77156
let nthreads = match os::getenv("RUST_RT_TEST_THREADS") {
78157
Some(nstr) => FromStr::from_str(nstr).get(),
79158
None => {
80-
// A reasonable number of threads for testing
81-
// multithreading. NB: It's easy to exhaust OS X's
82-
// low maximum fd limit by setting this too high (#7772)
83-
4
159+
// Using more threads than cores in test code
160+
// to force the OS to preempt them frequently.
161+
// Assuming that this help stress test concurrent types.
162+
util::num_cpus() * 2
84163
}
85164
};
86165

0 commit comments

Comments
 (0)