std: adjust requested stack size for thread-local storage.
If there is a lot of data in thread-local storage some implementations of pthreads (e.g. glibc) fail if you don't request a stack large enough -- by adjusting for the minimum size we guarantee that our stacks are always large enough. Issue #6233.
This commit is contained in:
parent
27ce4d3f79
commit
f1b5f59287
2 changed files with 41 additions and 1 deletions
|
@ -202,8 +202,10 @@ mod imp {
|
||||||
let mut native: libc::pthread_t = intrinsics::uninit();
|
let mut native: libc::pthread_t = intrinsics::uninit();
|
||||||
let mut attr: libc::pthread_attr_t = intrinsics::uninit();
|
let mut attr: libc::pthread_attr_t = intrinsics::uninit();
|
||||||
assert_eq!(pthread_attr_init(&mut attr), 0);
|
assert_eq!(pthread_attr_init(&mut attr), 0);
|
||||||
|
|
||||||
|
let min_stack = get_min_stack(&attr);
|
||||||
assert_eq!(pthread_attr_setstacksize(&mut attr,
|
assert_eq!(pthread_attr_setstacksize(&mut attr,
|
||||||
stack as libc::size_t), 0);
|
min_stack + stack as libc::size_t), 0);
|
||||||
assert_eq!(pthread_attr_setdetachstate(&mut attr,
|
assert_eq!(pthread_attr_setdetachstate(&mut attr,
|
||||||
PTHREAD_CREATE_JOINABLE), 0);
|
PTHREAD_CREATE_JOINABLE), 0);
|
||||||
|
|
||||||
|
@ -228,6 +230,18 @@ mod imp {
|
||||||
#[cfg(not(target_os = "macos"), not(target_os = "android"))]
|
#[cfg(not(target_os = "macos"), not(target_os = "android"))]
|
||||||
pub unsafe fn yield_now() { assert_eq!(pthread_yield(), 0); }
|
pub unsafe fn yield_now() { assert_eq!(pthread_yield(), 0); }
|
||||||
|
|
||||||
|
// Issue #6233. On some platforms, putting a lot of data in
|
||||||
|
// thread-local storage means we need to set the stack-size to be
|
||||||
|
// larger.
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
unsafe fn get_min_stack(attr: &libc::pthread_attr_t) -> libc::size_t {
|
||||||
|
__pthread_get_minstack(attr)
|
||||||
|
}
|
||||||
|
#[cfg(not(target_os = "linux"))]
|
||||||
|
unsafe fn get_min_stack(_: &libc::pthread_attr_t) -> libc::size_t {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
fn pthread_create(native: *mut libc::pthread_t,
|
fn pthread_create(native: *mut libc::pthread_t,
|
||||||
attr: *libc::pthread_attr_t,
|
attr: *libc::pthread_attr_t,
|
||||||
|
@ -247,6 +261,10 @@ mod imp {
|
||||||
fn sched_yield() -> libc::c_int;
|
fn sched_yield() -> libc::c_int;
|
||||||
#[cfg(not(target_os = "macos"), not(target_os = "android"))]
|
#[cfg(not(target_os = "macos"), not(target_os = "android"))]
|
||||||
fn pthread_yield() -> libc::c_int;
|
fn pthread_yield() -> libc::c_int;
|
||||||
|
|
||||||
|
// This appears to be glibc specific
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn __pthread_get_minstack(attr: *libc::pthread_attr_t) -> libc::size_t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
22
src/test/run-pass/large-thread-local-data.rs
Normal file
22
src/test/run-pass/large-thread-local-data.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
// Issue #6233
|
||||||
|
// xfail-fast feature doesn't work
|
||||||
|
|
||||||
|
#[feature(thread_local)];
|
||||||
|
#[allow(dead_code)];
|
||||||
|
|
||||||
|
static SIZE: uint = 1 << 23;
|
||||||
|
|
||||||
|
#[thread_local]
|
||||||
|
static FOO: [u8, .. SIZE] = [0, .. SIZE];
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue