Skip to content

Commit

Permalink
std: adjust requested stack size for thread-local storage.
Browse files Browse the repository at this point in the history
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 rust-lang#6233.
  • Loading branch information
huonw committed Jan 4, 2014
1 parent 27ce4d3 commit f1b5f59
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
20 changes: 19 additions & 1 deletion src/libstd/rt/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,10 @@ mod imp {
let mut native: libc::pthread_t = intrinsics::uninit();
let mut attr: libc::pthread_attr_t = intrinsics::uninit();
assert_eq!(pthread_attr_init(&mut attr), 0);

let min_stack = get_min_stack(&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,
PTHREAD_CREATE_JOINABLE), 0);

Expand All @@ -228,6 +230,18 @@ mod imp {
#[cfg(not(target_os = "macos"), not(target_os = "android"))]
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 {
fn pthread_create(native: *mut libc::pthread_t,
attr: *libc::pthread_attr_t,
Expand All @@ -247,6 +261,10 @@ mod imp {
fn sched_yield() -> libc::c_int;
#[cfg(not(target_os = "macos"), not(target_os = "android"))]
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;
}
}

Expand Down
22 changes: 22 additions & 0 deletions src/test/run-pass/large-thread-local-data.rs
Original file line number Diff line number Diff line change
@@ -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() {}

1 comment on commit f1b5f59

@alexcrichton
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r+, I agree with your assessment on the issue that this is distasteful, but probably a good thing to do for now (due to the lack of activity)

Thanks for looking into this!

Please sign in to comment.