From 3db07cc379a881d942eef6d2248afaef89a8857a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Mon, 4 Jan 2016 12:32:22 +0100 Subject: [PATCH] osx: set the default thread stack size to RLIMIT_STACK Fixes: https://github.com/libuv/libuv/issues/669 PR-URL: https://github.com/libuv/libuv/pull/671 Reviewed-By: Ben Noordhuis --- src/unix/thread.c | 31 ++++++++++++++++++++++++++++++- test/test-list.h | 2 ++ test/test-thread.c | 21 +++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/unix/thread.c b/src/unix/thread.c index c56a3170..673e47e9 100644 --- a/src/unix/thread.c +++ b/src/unix/thread.c @@ -27,6 +27,7 @@ #include #include +#include /* getrlimit() */ #undef NANOSEC #define NANOSEC ((uint64_t) 1e9) @@ -55,6 +56,11 @@ static void* uv__thread_start(void *arg) int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) { struct thread_ctx* ctx; int err; + pthread_attr_t* attr; +#if defined(__APPLE__) + pthread_attr_t attr_storage; + struct rlimit lim; +#endif ctx = uv__malloc(sizeof(*ctx)); if (ctx == NULL) @@ -63,7 +69,30 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) { ctx->entry = entry; ctx->arg = arg; - err = pthread_create(tid, NULL, uv__thread_start, ctx); + /* On OSX threads other than the main thread are created with a reduced stack + * size by default, adjust it to RLIMIT_STACK. + */ +#if defined(__APPLE__) + if (getrlimit(RLIMIT_STACK, &lim)) + abort(); + + attr = &attr_storage; + if (pthread_attr_init(attr)) + abort(); + + if (lim.rlim_cur != RLIM_INFINITY && + lim.rlim_cur >= PTHREAD_STACK_MIN) { + if (pthread_attr_setstacksize(attr, lim.rlim_cur)) + abort(); + } +#else + attr = NULL; +#endif + + err = pthread_create(tid, attr, uv__thread_start, ctx); + + if (attr != NULL) + pthread_attr_destroy(attr); if (err) uv__free(ctx); diff --git a/test/test-list.h b/test/test-list.h index 42315b35..dce5de32 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -294,6 +294,7 @@ TEST_DECLARE (threadpool_cancel_work) TEST_DECLARE (threadpool_cancel_fs) TEST_DECLARE (threadpool_cancel_single) TEST_DECLARE (thread_local_storage) +TEST_DECLARE (thread_stack_size) TEST_DECLARE (thread_mutex) TEST_DECLARE (thread_rwlock) TEST_DECLARE (thread_rwlock_trylock) @@ -717,6 +718,7 @@ TASK_LIST_START TEST_ENTRY (threadpool_cancel_fs) TEST_ENTRY (threadpool_cancel_single) TEST_ENTRY (thread_local_storage) + TEST_ENTRY (thread_stack_size) TEST_ENTRY (thread_mutex) TEST_ENTRY (thread_rwlock) TEST_ENTRY (thread_rwlock_trylock) diff --git a/test/test-thread.c b/test/test-thread.c index 7f3321aa..10bec3fe 100644 --- a/test/test-thread.c +++ b/test/test-thread.c @@ -209,3 +209,24 @@ TEST_IMPL(thread_local_storage) { uv_key_delete(&tls_key); return 0; } + + +#if defined(__APPLE__) +static void thread_check_stack(void* arg) { + /* 512KB is the default stack size of threads other than the main thread + * on OSX. */ + ASSERT(pthread_get_stacksize_np(pthread_self()) > 512*1024); +} +#endif + + +TEST_IMPL(thread_stack_size) { +#if defined(__APPLE__) + uv_thread_t thread; + ASSERT(0 == uv_thread_create(&thread, thread_check_stack, NULL)); + ASSERT(0 == uv_thread_join(&thread)); + return 0; +#else + RETURN_SKIP("OSX only test"); +#endif +}