Boost logo

Boost :

Subject: Re: [boost] Gauging interest in patch submissions
From: Brett Lentz (blentz_at_[hidden])
Date: 2011-09-28 13:08:27


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();


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk