|  | @@ -31,6 +31,7 @@
 | 
	
		
			
				|  |  |  #include <pthread.h>
 | 
	
		
			
				|  |  |  #include <stdlib.h>
 | 
	
		
			
				|  |  |  #include <string.h>
 | 
	
		
			
				|  |  | +#include <unistd.h>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #include "src/core/lib/gpr/useful.h"
 | 
	
		
			
				|  |  |  #include "src/core/lib/gprpp/fork.h"
 | 
	
	
		
			
				|  | @@ -48,6 +49,26 @@ struct thd_arg {
 | 
	
		
			
				|  |  |    bool tracked;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +// TODO(yunjiaw): move this to a function-level static, or remove the use of a
 | 
	
		
			
				|  |  | +// non-constexpr initializer when possible
 | 
	
		
			
				|  |  | +const size_t page_size = static_cast<size_t>(sysconf(_SC_PAGESIZE));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +size_t RoundUpToPageSize(size_t size) {
 | 
	
		
			
				|  |  | +  return (size + page_size - 1) & ~(page_size - 1);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Returns the minimum valid stack size that can be passed to
 | 
	
		
			
				|  |  | +// pthread_attr_setstacksize.
 | 
	
		
			
				|  |  | +size_t MinValidStackSize(size_t request_size) {
 | 
	
		
			
				|  |  | +  if (request_size < _SC_THREAD_STACK_MIN) {
 | 
	
		
			
				|  |  | +    request_size = _SC_THREAD_STACK_MIN;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // On some systems, pthread_attr_setstacksize() can fail if stacksize is
 | 
	
		
			
				|  |  | +  // not a multiple of the system page size.
 | 
	
		
			
				|  |  | +  return RoundUpToPageSize(request_size);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  class ThreadInternalsPosix : public internal::ThreadInternalsInterface {
 | 
	
		
			
				|  |  |   public:
 | 
	
		
			
				|  |  |    ThreadInternalsPosix(const char* thd_name, void (*thd_body)(void* arg),
 | 
	
	
		
			
				|  | @@ -79,6 +100,11 @@ class ThreadInternalsPosix : public internal::ThreadInternalsInterface {
 | 
	
		
			
				|  |  |                   0);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    if (options.stack_size() != 0) {
 | 
	
		
			
				|  |  | +      size_t stack_size = MinValidStackSize(options.stack_size());
 | 
	
		
			
				|  |  | +      GPR_ASSERT(pthread_attr_setstacksize(&attr, stack_size) == 0);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      *success =
 | 
	
		
			
				|  |  |          (pthread_create(&pthread_id_, &attr,
 | 
	
		
			
				|  |  |                          [](void* v) -> void* {
 |