From f1b5f59287106fc511d29c425255bd343608065c Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Fri, 3 Jan 2014 14:27:13 +1100 Subject: [PATCH] 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. --- src/libstd/rt/thread.rs | 20 +++++++++++++++++- src/test/run-pass/large-thread-local-data.rs | 22 ++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/large-thread-local-data.rs diff --git a/src/libstd/rt/thread.rs b/src/libstd/rt/thread.rs index f4f4aaa276524..536043441e71c 100644 --- a/src/libstd/rt/thread.rs +++ b/src/libstd/rt/thread.rs @@ -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); @@ -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, @@ -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; } } diff --git a/src/test/run-pass/large-thread-local-data.rs b/src/test/run-pass/large-thread-local-data.rs new file mode 100644 index 0000000000000..90b4b806015f7 --- /dev/null +++ b/src/test/run-pass/large-thread-local-data.rs @@ -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 or the MIT license +// , 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() {}