aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2017-10-12 18:49:48 +0300
committerBoris Kolpackov <boris@codesynthesis.com>2017-10-13 10:28:25 +0200
commitf79a7e2cc674cae223e7a2df03aaad47978761e7 (patch)
treeddd852f68210abf24da5cee05a3836e00adbb8e6
parent28e325f0bd58bf11bd66997fff041d46b89b1cf1 (diff)
Make scheduler threads inherit stack size from main thread
-rw-r--r--build2/scheduler.cxx63
-rw-r--r--build2/scheduler.hxx7
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