Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: base/threading/platform_thread_posix.cc

Issue 1150563002: base/threading: Lazy thread startup for pthreads (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | base/threading/thread.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/threading/platform_thread.h" 5 #include "base/threading/platform_thread.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <pthread.h> 8 #include <pthread.h>
9 #include <sched.h> 9 #include <sched.h>
10 #include <sys/resource.h> 10 #include <sys/resource.h>
(...skipping 18 matching lines...) Expand all
29 29
30 void InitThreading(); 30 void InitThreading();
31 void InitOnThread(); 31 void InitOnThread();
32 void TerminateOnThread(); 32 void TerminateOnThread();
33 size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes); 33 size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes);
34 34
35 namespace { 35 namespace {
36 36
37 struct ThreadParams { 37 struct ThreadParams {
38 ThreadParams() 38 ThreadParams()
39 : delegate(NULL), 39 : delegate(NULL), joinable(false), priority(ThreadPriority::NORMAL) {}
40 joinable(false),
41 priority(ThreadPriority::NORMAL),
42 handle(NULL),
43 handle_set(false, false) {
44 }
45 40
46 PlatformThread::Delegate* delegate; 41 PlatformThread::Delegate* delegate;
47 bool joinable; 42 bool joinable;
48 ThreadPriority priority; 43 ThreadPriority priority;
49 PlatformThreadHandle* handle;
50 WaitableEvent handle_set;
Lei Zhang 2015/07/28 06:32:55 I think you can remove #include base/synchronizati
Takashi Toyoshima 2015/07/28 11:13:43 Done.
51 }; 44 };
52 45
53 void* ThreadFunc(void* params) { 46 void* ThreadFunc(void* params) {
47 CHECK(params);
Lei Zhang 2015/07/28 06:32:55 Is this needed? If the CHECK() fails, we'll just c
Takashi Toyoshima 2015/07/28 11:13:43 Agreed. I removed this redundant check.
54 base::InitOnThread(); 48 base::InitOnThread();
55 ThreadParams* thread_params = static_cast<ThreadParams*>(params); 49 scoped_ptr<ThreadParams> thread_params(static_cast<ThreadParams*>(params));
56 50
57 PlatformThread::Delegate* delegate = thread_params->delegate; 51 PlatformThread::Delegate* delegate = thread_params->delegate;
58 if (!thread_params->joinable) 52 if (!thread_params->joinable)
59 base::ThreadRestrictions::SetSingletonAllowed(false); 53 base::ThreadRestrictions::SetSingletonAllowed(false);
60 54
61 if (thread_params->priority != ThreadPriority::NORMAL) 55 if (thread_params->priority != ThreadPriority::NORMAL)
62 PlatformThread::SetCurrentThreadPriority(thread_params->priority); 56 PlatformThread::SetCurrentThreadPriority(thread_params->priority);
63 57
64 // Stash the id in the handle so the calling thread has a complete
65 // handle, and unblock the parent thread.
66 *(thread_params->handle) = PlatformThreadHandle(pthread_self());
67 thread_params->handle_set.Signal();
68
69 ThreadIdNameManager::GetInstance()->RegisterThread( 58 ThreadIdNameManager::GetInstance()->RegisterThread(
70 PlatformThread::CurrentHandle().platform_handle(), 59 PlatformThread::CurrentHandle().platform_handle(),
71 PlatformThread::CurrentId()); 60 PlatformThread::CurrentId());
72 61
73 delegate->ThreadMain(); 62 delegate->ThreadMain();
74 63
75 ThreadIdNameManager::GetInstance()->RemoveName( 64 ThreadIdNameManager::GetInstance()->RemoveName(
76 PlatformThread::CurrentHandle().platform_handle(), 65 PlatformThread::CurrentHandle().platform_handle(),
77 PlatformThread::CurrentId()); 66 PlatformThread::CurrentId());
78 67
79 base::TerminateOnThread(); 68 base::TerminateOnThread();
80 return NULL; 69 return NULL;
81 } 70 }
82 71
83 bool CreateThread(size_t stack_size, bool joinable, 72 bool CreateThread(size_t stack_size,
73 bool joinable,
84 PlatformThread::Delegate* delegate, 74 PlatformThread::Delegate* delegate,
85 PlatformThreadHandle* thread_handle, 75 PlatformThreadHandle* thread_handle,
86 ThreadPriority priority) { 76 ThreadPriority priority) {
77 CHECK(thread_handle);
Lei Zhang 2015/07/28 06:32:55 Will a DCHECK() suffice here?
Takashi Toyoshima 2015/07/28 11:13:43 Agreed. This check should be safe to ignore in rel
87 base::InitThreading(); 78 base::InitThreading();
88 79
89 bool success = false;
90 pthread_attr_t attributes; 80 pthread_attr_t attributes;
91 pthread_attr_init(&attributes); 81 pthread_attr_init(&attributes);
92 82
93 // Pthreads are joinable by default, so only specify the detached 83 // Pthreads are joinable by default, so only specify the detached
94 // attribute if the thread should be non-joinable. 84 // attribute if the thread should be non-joinable.
95 if (!joinable) { 85 if (!joinable)
96 pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED); 86 pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
97 }
98 87
99 // Get a better default if available. 88 // Get a better default if available.
100 if (stack_size == 0) 89 if (stack_size == 0)
101 stack_size = base::GetDefaultThreadStackSize(attributes); 90 stack_size = base::GetDefaultThreadStackSize(attributes);
102 91
103 if (stack_size > 0) 92 if (stack_size > 0)
104 pthread_attr_setstacksize(&attributes, stack_size); 93 pthread_attr_setstacksize(&attributes, stack_size);
105 94
106 ThreadParams params; 95 scoped_ptr<ThreadParams> params(new ThreadParams);
107 params.delegate = delegate; 96 params->delegate = delegate;
108 params.joinable = joinable; 97 params->joinable = joinable;
109 params.priority = priority; 98 params->priority = priority;
110 params.handle = thread_handle;
111 99
112 pthread_t handle; 100 pthread_t handle;
113 int err = pthread_create(&handle, 101 int err =
114 &attributes, 102 pthread_create(&handle, &attributes, ThreadFunc, params.get());
115 ThreadFunc, 103 bool success = !err;
116 &params); 104 if (success) {
117 success = !err; 105 // ThreadParams should be deleted on the created thread after used.
118 if (!success) { 106 ignore_result(params.release());
107 } else {
119 // Value of |handle| is undefined if pthread_create fails. 108 // Value of |handle| is undefined if pthread_create fails.
120 handle = 0; 109 handle = 0;
121 errno = err; 110 errno = err;
122 PLOG(ERROR) << "pthread_create"; 111 PLOG(ERROR) << "pthread_create";
123 } 112 }
113 *thread_handle = PlatformThreadHandle(handle);
124 114
125 pthread_attr_destroy(&attributes); 115 pthread_attr_destroy(&attributes);
126 116
127 // Don't let this call complete until the thread id
128 // is set in the handle.
129 if (success)
130 params.handle_set.Wait();
131 CHECK_EQ(handle, thread_handle->platform_handle());
132
133 return success; 117 return success;
134 } 118 }
135 119
136 } // namespace 120 } // namespace
137 121
138 // static 122 // static
139 PlatformThreadId PlatformThread::CurrentId() { 123 PlatformThreadId PlatformThread::CurrentId() {
140 // Pthreads doesn't have the concept of a thread ID, so we have to reach down 124 // Pthreads doesn't have the concept of a thread ID, so we have to reach down
141 // into the kernel. 125 // into the kernel.
142 #if defined(OS_MACOSX) 126 #if defined(OS_MACOSX)
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 173
190 // static 174 // static
191 const char* PlatformThread::GetName() { 175 const char* PlatformThread::GetName() {
192 return ThreadIdNameManager::GetInstance()->GetName(CurrentId()); 176 return ThreadIdNameManager::GetInstance()->GetName(CurrentId());
193 } 177 }
194 178
195 // static 179 // static
196 bool PlatformThread::CreateWithPriority(size_t stack_size, Delegate* delegate, 180 bool PlatformThread::CreateWithPriority(size_t stack_size, Delegate* delegate,
197 PlatformThreadHandle* thread_handle, 181 PlatformThreadHandle* thread_handle,
198 ThreadPriority priority) { 182 ThreadPriority priority) {
199 base::ThreadRestrictions::ScopedAllowWait allow_wait;
200 return CreateThread(stack_size, true, // joinable thread 183 return CreateThread(stack_size, true, // joinable thread
201 delegate, thread_handle, priority); 184 delegate, thread_handle, priority);
202 } 185 }
203 186
204 // static 187 // static
205 bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) { 188 bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) {
206 PlatformThreadHandle unused; 189 PlatformThreadHandle unused;
207 190
208 base::ThreadRestrictions::ScopedAllowWait allow_wait;
209 bool result = CreateThread(stack_size, false /* non-joinable thread */, 191 bool result = CreateThread(stack_size, false /* non-joinable thread */,
210 delegate, &unused, ThreadPriority::NORMAL); 192 delegate, &unused, ThreadPriority::NORMAL);
211 return result; 193 return result;
212 } 194 }
213 195
214 // static 196 // static
215 void PlatformThread::Join(PlatformThreadHandle thread_handle) { 197 void PlatformThread::Join(PlatformThreadHandle thread_handle) {
216 // Joining another thread may block the current thread for a long time, since 198 // Joining another thread may block the current thread for a long time, since
217 // the thread referred to by |thread_handle| may still be running long-lived / 199 // the thread referred to by |thread_handle| may still be running long-lived /
218 // blocking tasks. 200 // blocking tasks.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 return ThreadPriority::NORMAL; 250 return ThreadPriority::NORMAL;
269 } 251 }
270 252
271 return internal::NiceValueToThreadPriority(nice_value); 253 return internal::NiceValueToThreadPriority(nice_value);
272 #endif // !defined(OS_NACL) 254 #endif // !defined(OS_NACL)
273 } 255 }
274 256
275 #endif // !defined(OS_MACOSX) 257 #endif // !defined(OS_MACOSX)
276 258
277 } // namespace base 259 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | base/threading/thread.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698