about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2014-01-03 14:27:13 +1100
committerHuon Wilson <dbau.pp+github@gmail.com>2014-01-04 11:07:02 +1100
commitf1b5f59287106fc511d29c425255bd343608065c (patch)
tree32229a1e9cb36776ec5915d3c670217414067fb8 /src/libstd/rt
parent27ce4d3f79cdc021a6bfe0f7009977e07a368770 (diff)
downloadrust-f1b5f59287106fc511d29c425255bd343608065c.tar.gz
rust-f1b5f59287106fc511d29c425255bd343608065c.zip
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.
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/thread.rs20
1 files changed, 19 insertions, 1 deletions
diff --git a/src/libstd/rt/thread.rs b/src/libstd/rt/thread.rs
index f4f4aaa2765..536043441e7 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;
     }
 }