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

Side by Side Diff: components/nacl/renderer/plugin/pnacl_translate_thread.cc

Issue 1128943003: Move PNaCl process startup back to the main thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove unused field Created 5 years, 7 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
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 "components/nacl/renderer/plugin/pnacl_translate_thread.h" 5 #include "components/nacl/renderer/plugin/pnacl_translate_thread.h"
6 6
7 #include <iterator> 7 #include <iterator>
8 #include <sstream> 8 #include <sstream>
9 9
10 #include "components/nacl/renderer/plugin/plugin.h" 10 #include "components/nacl/renderer/plugin/plugin.h"
11 #include "components/nacl/renderer/plugin/plugin_error.h" 11 #include "components/nacl/renderer/plugin/plugin_error.h"
12 #include "components/nacl/renderer/plugin/pnacl_resources.h"
13 #include "components/nacl/renderer/plugin/srpc_params.h" 12 #include "components/nacl/renderer/plugin/srpc_params.h"
14 #include "components/nacl/renderer/plugin/temporary_file.h" 13 #include "components/nacl/renderer/plugin/temporary_file.h"
15 #include "components/nacl/renderer/plugin/utility.h" 14 #include "components/nacl/renderer/plugin/utility.h"
16 #include "native_client/src/shared/platform/nacl_check.h" 15 #include "native_client/src/shared/platform/nacl_check.h"
17 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" 16 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
18 #include "ppapi/cpp/var.h" 17 #include "ppapi/cpp/var.h"
19 18
20 namespace plugin { 19 namespace plugin {
21 namespace { 20 namespace {
22 21
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 66
68 for (const std::string& arg : args) { 67 for (const std::string& arg : args) {
69 std::copy(arg.begin(), arg.end(), std::back_inserter(*split_args)); 68 std::copy(arg.begin(), arg.end(), std::back_inserter(*split_args));
70 split_args->push_back('\x00'); 69 split_args->push_back('\x00');
71 } 70 }
72 } 71 }
73 72
74 } // namespace 73 } // namespace
75 74
76 PnaclTranslateThread::PnaclTranslateThread() 75 PnaclTranslateThread::PnaclTranslateThread()
77 : compiler_subprocess_active_(false), 76 : compiler_subprocess_(NULL),
77 ld_subprocess_(NULL),
78 compiler_subprocess_active_(false),
78 ld_subprocess_active_(false), 79 ld_subprocess_active_(false),
79 subprocesses_aborted_(false),
80 done_(false), 80 done_(false),
81 compile_time_(0), 81 compile_time_(0),
82 obj_files_(NULL), 82 obj_files_(NULL),
83 num_threads_(0), 83 num_threads_(0),
84 nexe_file_(NULL), 84 nexe_file_(NULL),
85 coordinator_error_info_(NULL), 85 coordinator_error_info_(NULL),
86 resources_(NULL), 86 coordinator_(NULL) {
87 coordinator_(NULL),
88 plugin_(NULL) {
89 NaClXMutexCtor(&subprocess_mu_); 87 NaClXMutexCtor(&subprocess_mu_);
90 NaClXMutexCtor(&cond_mu_); 88 NaClXMutexCtor(&cond_mu_);
91 NaClXCondVarCtor(&buffer_cond_); 89 NaClXCondVarCtor(&buffer_cond_);
92 } 90 }
93 91
94 void PnaclTranslateThread::RunTranslate( 92 void PnaclTranslateThread::SetupState(
95 const pp::CompletionCallback& finish_callback, 93 const pp::CompletionCallback& finish_callback,
94 NaClSubprocess* compiler_subprocess,
95 NaClSubprocess* ld_subprocess,
96 const std::vector<TempFile*>* obj_files, 96 const std::vector<TempFile*>* obj_files,
97 int num_threads, 97 int num_threads,
98 TempFile* nexe_file, 98 TempFile* nexe_file,
99 nacl::DescWrapper* invalid_desc_wrapper, 99 nacl::DescWrapper* invalid_desc_wrapper,
100 ErrorInfo* error_info, 100 ErrorInfo* error_info,
101 PnaclResources* resources,
102 PP_PNaClOptions* pnacl_options, 101 PP_PNaClOptions* pnacl_options,
103 const std::string& architecture_attributes, 102 const std::string& architecture_attributes,
104 PnaclCoordinator* coordinator, 103 PnaclCoordinator* coordinator) {
105 Plugin* plugin) { 104 PLUGIN_PRINTF(("PnaclTranslateThread::SetupState)\n"));
106 PLUGIN_PRINTF(("PnaclStreamingTranslateThread::RunTranslate)\n")); 105 compiler_subprocess_ = compiler_subprocess;
106 ld_subprocess_ = ld_subprocess;
107 obj_files_ = obj_files; 107 obj_files_ = obj_files;
108 num_threads_ = num_threads; 108 num_threads_ = num_threads;
109 nexe_file_ = nexe_file; 109 nexe_file_ = nexe_file;
110 invalid_desc_wrapper_ = invalid_desc_wrapper; 110 invalid_desc_wrapper_ = invalid_desc_wrapper;
111 coordinator_error_info_ = error_info; 111 coordinator_error_info_ = error_info;
112 resources_ = resources;
113 pnacl_options_ = pnacl_options; 112 pnacl_options_ = pnacl_options;
114 architecture_attributes_ = architecture_attributes; 113 architecture_attributes_ = architecture_attributes;
115 coordinator_ = coordinator; 114 coordinator_ = coordinator;
116 plugin_ = plugin;
117 115
118 // Invoke llc followed by ld off the main thread. This allows use of 116 // Invoke llc followed by ld off the main thread. This allows use of
Derek Schuff 2015/05/08 22:45:59 move or remove this comment.
jvoung (off chromium) 2015/05/08 23:59:32 Done.
119 // blocking RPCs that would otherwise block the JavaScript main thread. 117 // blocking RPCs that would otherwise block the JavaScript main thread.
120 report_translate_finished_ = finish_callback; 118 report_translate_finished_ = finish_callback;
119 }
120
121 void PnaclTranslateThread::RunCompile(
122 const pp::CompletionCallback& compile_finished_callback) {
123 PLUGIN_PRINTF(("PnaclTranslateThread::RunCompile)\n"));
124 DCHECK(started());
125 DCHECK(compiler_subprocess_->service_runtime());
126 compiler_subprocess_active_ = true;
127
128 compile_finished_callback_ = compile_finished_callback;
121 translate_thread_.reset(new NaClThread); 129 translate_thread_.reset(new NaClThread);
122 if (translate_thread_ == NULL) { 130 if (translate_thread_ == NULL) {
123 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE, 131 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE,
132 "could not allocate thread struct.");
133 return;
134 }
135 const int32_t kArbitraryStackSize = 128 * 1024;
136 if (!NaClThreadCreateJoinable(translate_thread_.get(), DoCompileThread, this,
137 kArbitraryStackSize)) {
138 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE,
139 "could not create thread.");
140 translate_thread_.reset(NULL);
141 }
142 }
143
144 void PnaclTranslateThread::RunLink() {
145 PLUGIN_PRINTF(("PnaclTranslateThread::RunLink)\n"));
146 DCHECK(started());
147 DCHECK(ld_subprocess_->service_runtime());
148 ld_subprocess_active_ = true;
149
150 // Tear down the previous thread.
Derek Schuff 2015/05/08 22:45:59 why tear down and fork again instead of reusing th
jvoung (off chromium) 2015/05/08 23:59:32 Ideally we would have a "PostTask" e.g., if we use
Derek Schuff 2015/05/09 00:18:32 This does seem simpler, and probably not too bad f
151 NaClThreadJoin(translate_thread_.get());
152 translate_thread_.reset(new NaClThread);
153 if (translate_thread_ == NULL) {
154 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE,
124 "could not allocate thread struct."); 155 "could not allocate thread struct.");
125 return; 156 return;
126 } 157 }
127 const int32_t kArbitraryStackSize = 128 * 1024; 158 const int32_t kArbitraryStackSize = 128 * 1024;
128 if (!NaClThreadCreateJoinable(translate_thread_.get(), 159 if (!NaClThreadCreateJoinable(translate_thread_.get(), DoLinkThread, this,
129 DoTranslateThread,
130 this,
131 kArbitraryStackSize)) { 160 kArbitraryStackSize)) {
132 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE, 161 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE,
133 "could not create thread."); 162 "could not create thread.");
134 translate_thread_.reset(NULL); 163 translate_thread_.reset(NULL);
135 } 164 }
136 } 165 }
137 166
138 // Called from main thread to send bytes to the translator. 167 // Called from main thread to send bytes to the translator.
139 void PnaclTranslateThread::PutBytes(const void* bytes, int32_t count) { 168 void PnaclTranslateThread::PutBytes(const void* bytes, int32_t count) {
140 CHECK(bytes != NULL); 169 CHECK(bytes != NULL);
141 NaClXMutexLock(&cond_mu_); 170 NaClXMutexLock(&cond_mu_);
142 data_buffers_.push_back(std::vector<char>()); 171 data_buffers_.push_back(std::vector<char>());
143 data_buffers_.back().insert(data_buffers_.back().end(), 172 data_buffers_.back().insert(data_buffers_.back().end(),
144 static_cast<const char*>(bytes), 173 static_cast<const char*>(bytes),
145 static_cast<const char*>(bytes) + count); 174 static_cast<const char*>(bytes) + count);
146 NaClXCondVarSignal(&buffer_cond_); 175 NaClXCondVarSignal(&buffer_cond_);
147 NaClXMutexUnlock(&cond_mu_); 176 NaClXMutexUnlock(&cond_mu_);
148 } 177 }
149 178
150 void PnaclTranslateThread::EndStream() { 179 void PnaclTranslateThread::EndStream() {
151 NaClXMutexLock(&cond_mu_); 180 NaClXMutexLock(&cond_mu_);
152 done_ = true; 181 done_ = true;
153 NaClXCondVarSignal(&buffer_cond_); 182 NaClXCondVarSignal(&buffer_cond_);
154 NaClXMutexUnlock(&cond_mu_); 183 NaClXMutexUnlock(&cond_mu_);
155 } 184 }
156 185
157 void WINAPI PnaclTranslateThread::DoTranslateThread(void* arg) { 186 void WINAPI PnaclTranslateThread::DoCompileThread(void* arg) {
158 PnaclTranslateThread* translator = 187 PnaclTranslateThread* translator =
159 reinterpret_cast<PnaclTranslateThread*>(arg); 188 reinterpret_cast<PnaclTranslateThread*>(arg);
160 translator->DoTranslate(); 189 translator->DoCompile();
161 } 190 }
162 191
163 void PnaclTranslateThread::DoTranslate() { 192 void PnaclTranslateThread::DoCompile() {
164 ErrorInfo error_info; 193 // If the main thread asked us to exit, just leave now.
194 NaClXMutexLock(&subprocess_mu_);
195 if (!compiler_subprocess_active_)
Derek Schuff 2015/05/08 22:45:59 is it intentional to return with the mutex still l
jvoung (off chromium) 2015/05/08 23:59:32 Nope =) Done.
196 return;
197 NaClXMutexUnlock(&subprocess_mu_);
198
199 // Wait till we are in the helper thread to do the blocking
Derek Schuff 2015/05/08 22:45:59 maybe say "now that we are in the helper thread, w
jvoung (off chromium) 2015/05/08 23:59:32 Done.
200 // StartSrpcServices operation.
201 if (!compiler_subprocess_->StartSrpcServices()) {
202 TranslateFailed(
203 PP_NACL_ERROR_SRPC_CONNECTION_FAIL,
204 "SRPC connection failure for " + compiler_subprocess_->description());
205 return;
206 }
207
165 SrpcParams params; 208 SrpcParams params;
166 std::vector<nacl::DescWrapper*> compile_out_files; 209 std::vector<nacl::DescWrapper*> compile_out_files;
167 size_t i; 210 size_t i;
168 for (i = 0; i < obj_files_->size(); i++) 211 for (i = 0; i < obj_files_->size(); i++)
169 compile_out_files.push_back((*obj_files_)[i]->write_wrapper()); 212 compile_out_files.push_back((*obj_files_)[i]->write_wrapper());
170 for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++) 213 for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++)
171 compile_out_files.push_back(invalid_desc_wrapper_); 214 compile_out_files.push_back(invalid_desc_wrapper_);
172 215
173 PLUGIN_PRINTF( 216 PLUGIN_PRINTF(("DoCompile using subzero: %d\n", pnacl_options_->use_subzero));
174 ("DoTranslate using subzero: %d\n", pnacl_options_->use_subzero));
175 217
176 pp::Core* core = pp::Module::Get()->core(); 218 pp::Core* core = pp::Module::Get()->core();
177 int64_t compiler_load_start_time = NaClGetTimeOfDayMicroseconds();
178 PnaclResources::ResourceType compiler_type = pnacl_options_->use_subzero
179 ? PnaclResources::SUBZERO
180 : PnaclResources::LLC;
181 // On success, ownership of file_info is transferred.
182 PP_NaClFileInfo file_info = resources_->TakeFileInfo(compiler_type);
183 const std::string& url = resources_->GetUrl(compiler_type);
184 NaClSubprocess* compiler_subprocess =
185 plugin_->LoadHelperNaClModule(url, file_info, &error_info);
186 if (compiler_subprocess == NULL) {
187 if (file_info.handle != PP_kInvalidFileHandle)
188 CloseFileHandle(file_info.handle);
189 TranslateFailed(PP_NACL_ERROR_PNACL_LLC_SETUP,
190 "Compile process could not be created: " +
191 error_info.message());
192 return;
193 }
194 int64_t compiler_load_time_total =
195 NaClGetTimeOfDayMicroseconds() - compiler_load_start_time;
196 GetNaClInterface()->LogTranslateTime("NaCl.Perf.PNaClLoadTime.LoadCompiler",
197 compiler_load_time_total);
198 GetNaClInterface()->LogTranslateTime(
199 pnacl_options_->use_subzero
200 ? "NaCl.Perf.PNaClLoadTime.LoadCompiler.Subzero"
201 : "NaCl.Perf.PNaClLoadTime.LoadCompiler.LLC",
202 compiler_load_time_total);
203
204 {
205 nacl::MutexLocker ml(&subprocess_mu_);
206 // If we received a call to AbortSubprocesses() before we had a chance to
207 // set compiler_subprocess_, shut down and clean up the subprocess started
208 // here.
209 if (subprocesses_aborted_) {
210 compiler_subprocess->service_runtime()->Shutdown();
211 delete compiler_subprocess;
212 return;
213 }
214 compiler_subprocess_.reset(compiler_subprocess);
215 compiler_subprocess = NULL;
216 compiler_subprocess_active_ = true;
217 }
218
219 int64_t do_compile_start_time = NaClGetTimeOfDayMicroseconds(); 219 int64_t do_compile_start_time = NaClGetTimeOfDayMicroseconds();
220 bool init_success; 220 bool init_success;
221 221
222 std::vector<char> split_args; 222 std::vector<char> split_args;
223 if (pnacl_options_->use_subzero) { 223 if (pnacl_options_->use_subzero) {
224 GetSubzeroCommandLine(&split_args, pnacl_options_->opt_level, 224 GetSubzeroCommandLine(&split_args, pnacl_options_->opt_level,
225 pnacl_options_->is_debug, architecture_attributes_); 225 pnacl_options_->is_debug, architecture_attributes_);
226 } else { 226 } else {
227 GetLlcCommandLine(&split_args, obj_files_->size(), 227 GetLlcCommandLine(&split_args, obj_files_->size(),
228 pnacl_options_->opt_level, pnacl_options_->is_debug, 228 pnacl_options_->opt_level, pnacl_options_->is_debug,
229 architecture_attributes_); 229 architecture_attributes_);
230 } 230 }
231
231 init_success = compiler_subprocess_->InvokeSrpcMethod( 232 init_success = compiler_subprocess_->InvokeSrpcMethod(
232 "StreamInitWithSplit", "ihhhhhhhhhhhhhhhhC", &params, num_threads_, 233 "StreamInitWithSplit", "ihhhhhhhhhhhhhhhhC", &params, num_threads_,
233 compile_out_files[0]->desc(), compile_out_files[1]->desc(), 234 compile_out_files[0]->desc(), compile_out_files[1]->desc(),
234 compile_out_files[2]->desc(), compile_out_files[3]->desc(), 235 compile_out_files[2]->desc(), compile_out_files[3]->desc(),
235 compile_out_files[4]->desc(), compile_out_files[5]->desc(), 236 compile_out_files[4]->desc(), compile_out_files[5]->desc(),
236 compile_out_files[6]->desc(), compile_out_files[7]->desc(), 237 compile_out_files[6]->desc(), compile_out_files[7]->desc(),
237 compile_out_files[8]->desc(), compile_out_files[9]->desc(), 238 compile_out_files[8]->desc(), compile_out_files[9]->desc(),
238 compile_out_files[10]->desc(), compile_out_files[11]->desc(), 239 compile_out_files[10]->desc(), compile_out_files[11]->desc(),
239 compile_out_files[12]->desc(), compile_out_files[13]->desc(), 240 compile_out_files[12]->desc(), compile_out_files[13]->desc(),
240 compile_out_files[14]->desc(), compile_out_files[15]->desc(), 241 compile_out_files[14]->desc(), compile_out_files[15]->desc(),
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 } 313 }
313 compile_time_ = NaClGetTimeOfDayMicroseconds() - do_compile_start_time; 314 compile_time_ = NaClGetTimeOfDayMicroseconds() - do_compile_start_time;
314 GetNaClInterface()->LogTranslateTime("NaCl.Perf.PNaClLoadTime.CompileTime", 315 GetNaClInterface()->LogTranslateTime("NaCl.Perf.PNaClLoadTime.CompileTime",
315 compile_time_); 316 compile_time_);
316 GetNaClInterface()->LogTranslateTime( 317 GetNaClInterface()->LogTranslateTime(
317 pnacl_options_->use_subzero 318 pnacl_options_->use_subzero
318 ? "NaCl.Perf.PNaClLoadTime.CompileTime.Subzero" 319 ? "NaCl.Perf.PNaClLoadTime.CompileTime.Subzero"
319 : "NaCl.Perf.PNaClLoadTime.CompileTime.LLC", 320 : "NaCl.Perf.PNaClLoadTime.CompileTime.LLC",
320 compile_time_); 321 compile_time_);
321 322
322 // Shut down the llc subprocess. 323 // Shut down the compiler subprocess.
323 NaClXMutexLock(&subprocess_mu_); 324 NaClXMutexLock(&subprocess_mu_);
324 compiler_subprocess_active_ = false; 325 compiler_subprocess_active_ = false;
325 compiler_subprocess_.reset(NULL); 326 compiler_subprocess_->Shutdown();
326 NaClXMutexUnlock(&subprocess_mu_); 327 NaClXMutexUnlock(&subprocess_mu_);
327 328
328 if(!RunLdSubprocess()) { 329 core->CallOnMainThread(0, compile_finished_callback_, PP_OK);
330 }
331
332 void WINAPI PnaclTranslateThread::DoLinkThread(void* arg) {
333 PnaclTranslateThread* translator =
334 reinterpret_cast<PnaclTranslateThread*>(arg);
335 translator->DoLink();
336 }
337
338 void PnaclTranslateThread::DoLink() {
339 // If the main thread asked us to exit in between starting the thread
340 // and now, just leave now.
341 NaClXMutexLock(&subprocess_mu_);
342 if (!ld_subprocess_active_)
343 return;
344 NaClXMutexUnlock(&subprocess_mu_);
345
346 // Wait till we are in the helper thread to do the blocking
Derek Schuff 2015/05/08 22:45:59 here too as above
jvoung (off chromium) 2015/05/08 23:59:32 Done.
347 // StartSrpcServices operation.
348 if (!ld_subprocess_->StartSrpcServices()) {
349 TranslateFailed(
350 PP_NACL_ERROR_SRPC_CONNECTION_FAIL,
351 "SRPC connection failure for " + ld_subprocess_->description());
329 return; 352 return;
330 } 353 }
331 core->CallOnMainThread(0, report_translate_finished_, PP_OK);
332 }
333 354
334 bool PnaclTranslateThread::RunLdSubprocess() {
335 ErrorInfo error_info;
336 SrpcParams params; 355 SrpcParams params;
337
338 std::vector<nacl::DescWrapper*> ld_in_files; 356 std::vector<nacl::DescWrapper*> ld_in_files;
339 size_t i; 357 size_t i;
340 for (i = 0; i < obj_files_->size(); i++) { 358 for (i = 0; i < obj_files_->size(); i++) {
341 // Reset object file for reading first. 359 // Reset object file for reading first.
342 if (!(*obj_files_)[i]->Reset()) { 360 if (!(*obj_files_)[i]->Reset()) {
343 TranslateFailed(PP_NACL_ERROR_PNACL_LD_SETUP, 361 TranslateFailed(PP_NACL_ERROR_PNACL_LD_SETUP,
344 "Link process could not reset object file"); 362 "Link process could not reset object file");
345 return false;
346 } 363 }
347 ld_in_files.push_back((*obj_files_)[i]->read_wrapper()); 364 ld_in_files.push_back((*obj_files_)[i]->read_wrapper());
348 } 365 }
349 for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++) 366 for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++)
350 ld_in_files.push_back(invalid_desc_wrapper_); 367 ld_in_files.push_back(invalid_desc_wrapper_);
351 368
352 nacl::DescWrapper* ld_out_file = nexe_file_->write_wrapper(); 369 nacl::DescWrapper* ld_out_file = nexe_file_->write_wrapper();
353 int64_t ld_start_time = NaClGetTimeOfDayMicroseconds();
354 PP_NaClFileInfo ld_file_info = resources_->TakeFileInfo(PnaclResources::LD);
355 // On success, ownership of ld_file_info is transferred.
356 nacl::scoped_ptr<NaClSubprocess> ld_subprocess(plugin_->LoadHelperNaClModule(
357 resources_->GetUrl(PnaclResources::LD), ld_file_info, &error_info));
358 if (ld_subprocess.get() == NULL) {
359 if (ld_file_info.handle != PP_kInvalidFileHandle)
360 CloseFileHandle(ld_file_info.handle);
361 TranslateFailed(PP_NACL_ERROR_PNACL_LD_SETUP,
362 "Link process could not be created: " +
363 error_info.message());
364 return false;
365 }
366 GetNaClInterface()->LogTranslateTime(
367 "NaCl.Perf.PNaClLoadTime.LoadLinker",
368 NaClGetTimeOfDayMicroseconds() - ld_start_time);
369 {
370 nacl::MutexLocker ml(&subprocess_mu_);
371 // If we received a call to AbortSubprocesses() before we had a chance to
372 // set ld_subprocess_, shut down and clean up the subprocess started here.
373 if (subprocesses_aborted_) {
374 ld_subprocess->service_runtime()->Shutdown();
375 return false;
376 }
377 DCHECK(ld_subprocess_.get() == NULL);
378 ld_subprocess_.swap(ld_subprocess);
379 ld_subprocess_active_ = true;
380 }
381
382 int64_t link_start_time = NaClGetTimeOfDayMicroseconds(); 370 int64_t link_start_time = NaClGetTimeOfDayMicroseconds();
383 // Run LD. 371 // Run LD.
384 bool success = ld_subprocess_->InvokeSrpcMethod( 372 bool success = ld_subprocess_->InvokeSrpcMethod(
385 "RunWithSplit", 373 "RunWithSplit",
386 "ihhhhhhhhhhhhhhhhh", 374 "ihhhhhhhhhhhhhhhhh",
387 &params, 375 &params,
388 static_cast<int>(obj_files_->size()), 376 static_cast<int>(obj_files_->size()),
389 ld_in_files[0]->desc(), 377 ld_in_files[0]->desc(),
390 ld_in_files[1]->desc(), 378 ld_in_files[1]->desc(),
391 ld_in_files[2]->desc(), 379 ld_in_files[2]->desc(),
392 ld_in_files[3]->desc(), 380 ld_in_files[3]->desc(),
393 ld_in_files[4]->desc(), 381 ld_in_files[4]->desc(),
394 ld_in_files[5]->desc(), 382 ld_in_files[5]->desc(),
395 ld_in_files[6]->desc(), 383 ld_in_files[6]->desc(),
396 ld_in_files[7]->desc(), 384 ld_in_files[7]->desc(),
397 ld_in_files[8]->desc(), 385 ld_in_files[8]->desc(),
398 ld_in_files[9]->desc(), 386 ld_in_files[9]->desc(),
399 ld_in_files[10]->desc(), 387 ld_in_files[10]->desc(),
400 ld_in_files[11]->desc(), 388 ld_in_files[11]->desc(),
401 ld_in_files[12]->desc(), 389 ld_in_files[12]->desc(),
402 ld_in_files[13]->desc(), 390 ld_in_files[13]->desc(),
403 ld_in_files[14]->desc(), 391 ld_in_files[14]->desc(),
404 ld_in_files[15]->desc(), 392 ld_in_files[15]->desc(),
405 ld_out_file->desc()); 393 ld_out_file->desc());
406 if (!success) { 394 if (!success) {
407 TranslateFailed(PP_NACL_ERROR_PNACL_LD_INTERNAL, 395 TranslateFailed(PP_NACL_ERROR_PNACL_LD_INTERNAL,
408 "link failed."); 396 "link failed.");
409 return false; 397 return;
410 } 398 }
411 GetNaClInterface()->LogTranslateTime( 399 GetNaClInterface()->LogTranslateTime(
412 "NaCl.Perf.PNaClLoadTime.LinkTime", 400 "NaCl.Perf.PNaClLoadTime.LinkTime",
413 NaClGetTimeOfDayMicroseconds() - link_start_time); 401 NaClGetTimeOfDayMicroseconds() - link_start_time);
414 PLUGIN_PRINTF(("PnaclCoordinator: link (translator=%p) succeeded\n", 402 PLUGIN_PRINTF(("PnaclCoordinator: link (translator=%p) succeeded\n",
415 this)); 403 this));
404
416 // Shut down the ld subprocess. 405 // Shut down the ld subprocess.
417 NaClXMutexLock(&subprocess_mu_); 406 NaClXMutexLock(&subprocess_mu_);
418 ld_subprocess_active_ = false; 407 ld_subprocess_active_ = false;
419 ld_subprocess_.reset(NULL); 408 ld_subprocess_->Shutdown();
420 NaClXMutexUnlock(&subprocess_mu_); 409 NaClXMutexUnlock(&subprocess_mu_);
421 return true; 410
411 pp::Core* core = pp::Module::Get()->core();
412 core->CallOnMainThread(0, report_translate_finished_, PP_OK);
422 } 413 }
423 414
424 void PnaclTranslateThread::TranslateFailed( 415 void PnaclTranslateThread::TranslateFailed(
425 PP_NaClError err_code, 416 PP_NaClError err_code,
426 const std::string& error_string) { 417 const std::string& error_string) {
427 PLUGIN_PRINTF(("PnaclTranslateThread::TranslateFailed (error_string='%s')\n", 418 PLUGIN_PRINTF(("PnaclTranslateThread::TranslateFailed (error_string='%s')\n",
428 error_string.c_str())); 419 error_string.c_str()));
429 pp::Core* core = pp::Module::Get()->core(); 420 pp::Core* core = pp::Module::Get()->core();
430 if (coordinator_error_info_->message().empty()) { 421 if (coordinator_error_info_->message().empty()) {
431 // Only use our message if one hasn't already been set by the coordinator 422 // Only use our message if one hasn't already been set by the coordinator
432 // (e.g. pexe load failed). 423 // (e.g. pexe load failed).
433 coordinator_error_info_->SetReport(err_code, 424 coordinator_error_info_->SetReport(err_code,
434 std::string("PnaclCoordinator: ") + 425 std::string("PnaclCoordinator: ") +
435 error_string); 426 error_string);
436 } 427 }
437 core->CallOnMainThread(0, report_translate_finished_, PP_ERROR_FAILED); 428 core->CallOnMainThread(0, report_translate_finished_, PP_ERROR_FAILED);
438 } 429 }
439 430
440 void PnaclTranslateThread::AbortSubprocesses() { 431 void PnaclTranslateThread::AbortSubprocesses() {
441 PLUGIN_PRINTF(("PnaclTranslateThread::AbortSubprocesses\n")); 432 PLUGIN_PRINTF(("PnaclTranslateThread::AbortSubprocesses\n"));
442 NaClXMutexLock(&subprocess_mu_); 433 NaClXMutexLock(&subprocess_mu_);
443 if (compiler_subprocess_ != NULL && compiler_subprocess_active_) { 434 if (compiler_subprocess_ != NULL && compiler_subprocess_active_) {
435 // We only run the service_runtime's Shutdown and do not run the
436 // NaClSubprocess Shutdown, which would otherwise nullify some
437 // pointers that could still be in use (srpc_client, etc.).
444 compiler_subprocess_->service_runtime()->Shutdown(); 438 compiler_subprocess_->service_runtime()->Shutdown();
445 compiler_subprocess_active_ = false; 439 compiler_subprocess_active_ = false;
446 } 440 }
447 if (ld_subprocess_ != NULL && ld_subprocess_active_) { 441 if (ld_subprocess_ != NULL && ld_subprocess_active_) {
448 ld_subprocess_->service_runtime()->Shutdown(); 442 ld_subprocess_->service_runtime()->Shutdown();
449 ld_subprocess_active_ = false; 443 ld_subprocess_active_ = false;
450 } 444 }
451 subprocesses_aborted_ = true;
452 NaClXMutexUnlock(&subprocess_mu_); 445 NaClXMutexUnlock(&subprocess_mu_);
453 nacl::MutexLocker ml(&cond_mu_); 446 nacl::MutexLocker ml(&cond_mu_);
454 done_ = true; 447 done_ = true;
455 // Free all buffered bitcode chunks 448 // Free all buffered bitcode chunks
456 data_buffers_.clear(); 449 data_buffers_.clear();
457 NaClXCondVarSignal(&buffer_cond_); 450 NaClXCondVarSignal(&buffer_cond_);
458 } 451 }
459 452
460 PnaclTranslateThread::~PnaclTranslateThread() { 453 PnaclTranslateThread::~PnaclTranslateThread() {
461 PLUGIN_PRINTF(("~PnaclTranslateThread (translate_thread=%p)\n", this)); 454 PLUGIN_PRINTF(("~PnaclTranslateThread (translate_thread=%p)\n", this));
462 AbortSubprocesses(); 455 AbortSubprocesses();
463 if (translate_thread_ != NULL) 456 if (translate_thread_ != NULL)
464 NaClThreadJoin(translate_thread_.get()); 457 NaClThreadJoin(translate_thread_.get());
465 PLUGIN_PRINTF(("~PnaclTranslateThread joined\n")); 458 PLUGIN_PRINTF(("~PnaclTranslateThread joined\n"));
466 NaClCondVarDtor(&buffer_cond_); 459 NaClCondVarDtor(&buffer_cond_);
467 NaClMutexDtor(&cond_mu_); 460 NaClMutexDtor(&cond_mu_);
468 NaClMutexDtor(&subprocess_mu_); 461 NaClMutexDtor(&subprocess_mu_);
469 } 462 }
470 463
471 } // namespace plugin 464 } // namespace plugin
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698