diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2017-10-12 18:49:48 +0300 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2017-10-13 10:28:25 +0200 |
commit | f79a7e2cc674cae223e7a2df03aaad47978761e7 (patch) | |
tree | ddd852f68210abf24da5cee05a3836e00adbb8e6 | |
parent | 28e325f0bd58bf11bd66997fff041d46b89b1cf1 (diff) |
Make scheduler threads inherit stack size from main thread
-rw-r--r-- | build2/scheduler.cxx | 63 | ||||
-rw-r--r-- | build2/scheduler.hxx | 7 |
2 files changed, 65 insertions, 5 deletions
diff --git a/build2/scheduler.cxx b/build2/scheduler.cxx index 86dbd5c..6ffbdc4 100644 --- a/build2/scheduler.cxx +++ b/build2/scheduler.cxx @@ -4,6 +4,10 @@ #include <build2/scheduler.hxx> +#ifdef __APPLE__ +#include <pthread.h> +#endif + #include <cerrno> using namespace std; @@ -441,13 +445,65 @@ namespace build2 } g {&l, helpers_, starting_}; + // On Mac OS (as of 10.12) the default stack size is 512K for threads + // other than the main one, and there is no way to change this once and + // for all newly created threads. For the main thread it is by default 8M. + // + // For Mac OS we will use pthreads, creating threads with the stack size + // of the current thread. This way all threads will inherit the main + // thread's stack size (since the first helper is always created by the + // main thread). + // +#ifndef __APPLE__ thread t (helper, this); - g.l = nullptr; // Disarm. - t.detach (); +#else + pthread_attr_t attr; + int r (pthread_attr_init (&attr)); + + if (r != 0) + throw_system_error (r); + + // Auto-deleter. + // + unique_ptr<pthread_attr_t, void (*)(pthread_attr_t*)> ad ( + &attr, + [] (pthread_attr_t* a) + { + int r (pthread_attr_destroy (a)); + + // We should be able to destroy the valid attributes object, unless + // something is severely damaged. + // + assert (r == 0); + }); + + // Create the thread already detached. + // + r = pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); + + if (r != 0) + throw_system_error (r); + + // Inherit the stack size from the current thread. + // + r = pthread_attr_setstacksize (&attr, + pthread_get_stacksize_np (pthread_self ())); + + if (r != 0) + throw_system_error (r); + + pthread_t t; + r = pthread_create (&t, &attr, helper, this); + + if (r != 0) + throw_system_error (r); +#endif + + g.l = nullptr; // Disarm. } - void scheduler:: + void* scheduler:: helper (void* d) { scheduler& s (*static_cast<scheduler*> (d)); @@ -513,6 +569,7 @@ namespace build2 } s.helpers_--; + return nullptr; } #ifdef __cpp_thread_local diff --git a/build2/scheduler.hxx b/build2/scheduler.hxx index 70dbf04..f79ca3e 100644 --- a/build2/scheduler.hxx +++ b/build2/scheduler.hxx @@ -326,9 +326,12 @@ namespace build2 create_helper (lock&); // We restrict ourselves to a single pointer as an argument in hope of - // a small object optimization. + // a small object optimization. Return NULL. // - static void + // Note that the return type is void* to make the function usable with + // pthreads (see scheduler.cxx for details). + // + static void* helper (void*); size_t |