43 class ThreadInternalsPosix;
46 ThreadInternalsPosix*
thread;
47 void (*body)(
void*
arg);
54 size_t RoundUpToPageSize(
size_t size) {
57 size_t page_size =
static_cast<size_t>(sysconf(_SC_PAGESIZE));
58 return (
size + page_size - 1) & ~(page_size - 1);
63 size_t MinValidStackSize(
size_t request_size) {
64 size_t min_stacksize = sysconf(_SC_THREAD_STACK_MIN);
65 if (request_size < min_stacksize) {
66 request_size = min_stacksize;
71 return RoundUpToPageSize(request_size);
74 class ThreadInternalsPosix :
public internal::ThreadInternalsInterface {
76 ThreadInternalsPosix(
const char* thd_name,
void (*thd_body)(
void*
arg),
77 void*
arg,
bool* success,
const Thread::Options&
options)
84 thd_arg* info =
static_cast<thd_arg*
>(malloc(
sizeof(*info)));
87 info->body = thd_body;
89 info->name = thd_name;
90 info->joinable =
options.joinable();
91 info->tracked =
options.tracked();
98 GPR_ASSERT(pthread_attr_setdetachstate(&
attr, PTHREAD_CREATE_JOINABLE) ==
101 GPR_ASSERT(pthread_attr_setdetachstate(&
attr, PTHREAD_CREATE_DETACHED) ==
105 if (
options.stack_size() != 0) {
106 size_t stack_size = MinValidStackSize(
options.stack_size());
110 *success = (pthread_create(
112 [](
void*
v) ->
void* {
113 thd_arg
arg = *
static_cast<thd_arg*
>(
v);
116 #if GPR_APPLE_PTHREAD_NAME
120 #elif GPR_LINUX_PTHREAD_NAME
127 pthread_setname_np(pthread_self(),
buf);
128 #endif // GPR_APPLE_PTHREAD_NAME
132 while (!
arg.thread->started_) {
161 ~ThreadInternalsPosix()
override {
166 void Start()
override {
173 void Join()
override { pthread_join(pthread_id_,
nullptr); }
179 pthread_t pthread_id_;
185 bool* success,
const Options&
options)
187 bool outcome =
false;
188 impl_ =
new ThreadInternalsPosix(thd_name, thd_body,
arg, &outcome,
options);
197 if (success !=
nullptr) {