
28 Sep
2011
28 Sep
'11
5:08 p.m.
On 09/28/2011 01:02 PM, Tim Moore wrote: > > On 9/28/11 8:48 AM, Brett Lentz wrote: >> >> 1. Adding an optional stack_size parameter to thread::start_thread() >> >> This is useful in Passenger's case where they want to reduce the VM size >> without requiring the user to hassle with ulimit settings on Linux. >> Passenger spawns many threads rather than using a thread pool for >> performance reasons. >> >> This change is, its current form, platform-specific, but I'm working on >> correcting that, hopefully without a ton of ifdefs. > > I would be interested in this capability but would want to see your > proposed changes. We have a patch that we apply for our own purposes of > adjusting the stack size but would be interested in a more general > solution. > > Tim > > Here's the patch against Boost 1.44. This is straight from the phusion repo. The only addition I've made is the comment about its platform-specific nature. ---Brett. diff --git a/boost/thread/detail/thread.hpp b/boost/thread/detail/thread.hpp index 26224ba..3db4b88 100644 --- a/boost/thread/detail/thread.hpp +++ b/boost/thread/detail/thread.hpp @@ -117,8 +117,6 @@ namespace boost detail::thread_data_ptr thread_info; - void start_thread(); - explicit thread(detail::thread_data_ptr data); detail::thread_data_ptr get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const; @@ -147,12 +145,22 @@ namespace boost #endif struct dummy; + + protected: + template <class F> + void set_thread_main_function(F f) + { + thread_info = make_thread_info(f); + } + + void start_thread(unsigned int stack_size = 0); + public: #if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) thread(const volatile thread&); #endif thread(); - ~thread(); + virtual ~thread(); #ifndef BOOST_NO_RVALUE_REFERENCES #ifdef BOOST_MSVC @@ -164,10 +172,10 @@ namespace boost } #else template <class F> - thread(F&& f): + thread(F&& f, unsigned int stack_size = 0): thread_info(make_thread_info(static_cast<F&&>(f))) { - start_thread(); + start_thread(stack_size); } #endif @@ -191,25 +199,25 @@ namespace boost #else #ifdef BOOST_NO_SFINAE template <class F> - explicit thread(F f): + explicit thread(F f, unsigned int stack_size = 0): thread_info(make_thread_info(f)) { - start_thread(); + start_thread(stack_size); } #else template <class F> - explicit thread(F f,typename disable_if<boost::is_convertible<F&,detail::thread_move_t<F> >, dummy* >::type=0): + explicit thread(F f,typename disable_if<boost::is_convertible<F&,detail::thread_move_t<F> >, dummy* >::type=0, unsigned int stack_size = 0): thread_info(make_thread_info(f)) { - start_thread(); + start_thread(stack_size); } #endif template <class F> - explicit thread(detail::thread_move_t<F> f): + explicit thread(detail::thread_move_t<F> f, unsigned int stack_size = 0): thread_info(make_thread_info(f)) { - start_thread(); + start_thread(stack_size); } thread(detail::thread_move_t<thread> x) @@ -246,65 +254,65 @@ namespace boost #endif template <class F,class A1> - thread(F f,A1 a1): + thread(F f,A1 a1, unsigned int stack_size = 0): thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1))) { - start_thread(); + start_thread(stack_size); } template <class F,class A1,class A2> - thread(F f,A1 a1,A2 a2): + thread(F f,A1 a1,A2 a2, unsigned int stack_size = 0): thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2))) { - start_thread(); + start_thread(stack_size); } template <class F,class A1,class A2,class A3> - thread(F f,A1 a1,A2 a2,A3 a3): + thread(F f,A1 a1,A2 a2,A3 a3, unsigned int stack_size = 0): thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3))) { - start_thread(); + start_thread(stack_size); } template <class F,class A1,class A2,class A3,class A4> - thread(F f,A1 a1,A2 a2,A3 a3,A4 a4): + thread(F f,A1 a1,A2 a2,A3 a3,A4 a4, unsigned int stack_size = 0): thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4))) { - start_thread(); + start_thread(stack_size); } template <class F,class A1,class A2,class A3,class A4,class A5> - thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5): + thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5, unsigned int stack_size = 0): thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5))) { - start_thread(); + start_thread(stack_size); } template <class F,class A1,class A2,class A3,class A4,class A5,class A6> - thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6): + thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6, unsigned int stack_size = 0): thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6))) { - start_thread(); + start_thread(stack_size); } template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7> - thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7): + thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7, unsigned int stack_size = 0): thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7))) { - start_thread(); + start_thread(stack_size); } template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7,class A8> - thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8): + thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8, unsigned int stack_size = 0): thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7,a8))) { - start_thread(); + start_thread(stack_size); } template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7,class A8,class A9> - thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9): + thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9, unsigned int stack_size = 0): thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7,a8,a9))) { - start_thread(); + start_thread(stack_size); } void swap(thread& x) diff --git a/libs/thread/src/pthread/thread.cpp b/libs/thread/src/pthread/thread.cpp index 4ff40a9..7571c9a 100644 --- a/libs/thread/src/pthread/thread.cpp +++ b/libs/thread/src/pthread/thread.cpp @@ -180,10 +180,25 @@ namespace boost thread::thread() {} - void thread::start_thread() + void thread::start_thread(unsigned int stack_size) { + /* FIXME: Linux-only. Breaks Win32. */ thread_info->self=thread_info; - int const res = pthread_create(&thread_info->thread_handle, 0, &thread_proxy, thread_info.get()); + pthread_attr_t attr; + int res = pthread_attr_init(&attr); + if (res != 0) { + throw thread_resource_error(); + } + if (stack_size > 0) { + res = pthread_attr_setstacksize(&attr, stack_size); + if (res != 0) { + pthread_attr_destroy(&attr); + throw thread_resource_error(); + } + } + + res = pthread_create(&thread_info->thread_handle, &attr, &thread_proxy, thread_info.get()); + pthread_attr_destroy(&attr); if (res != 0) { thread_info->self.reset();