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

Side by Side Diff: ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc

Issue 10827109: Simplify Pnacl translation thread code (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h ('k') | no next file » | 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 "native_client/src/trusted/plugin/pnacl_translate_thread.h" 5 #include "native_client/src/trusted/plugin/pnacl_translate_thread.h"
6 6
7 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" 7 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
8 #include "native_client/src/trusted/plugin/plugin.h" 8 #include "native_client/src/trusted/plugin/plugin.h"
9 #include "native_client/src/trusted/plugin/pnacl_resources.h" 9 #include "native_client/src/trusted/plugin/pnacl_resources.h"
10 #include "native_client/src/trusted/plugin/srpc_params.h" 10 #include "native_client/src/trusted/plugin/srpc_params.h"
11 #include "native_client/src/trusted/plugin/temporary_file.h" 11 #include "native_client/src/trusted/plugin/temporary_file.h"
12 #include "native_client/src/trusted/plugin/utility.h" 12 #include "native_client/src/trusted/plugin/utility.h"
13 13
14 namespace plugin { 14 namespace plugin {
15 15
16 PnaclTranslateThread::PnaclTranslateThread() : subprocesses_should_die_(false), 16 PnaclTranslateThread::PnaclTranslateThread() : subprocesses_should_die_(false),
17 current_rev_interface_(NULL), 17 current_rev_interface_(NULL),
18 done_(false),
18 manifest_(NULL), 19 manifest_(NULL),
19 ld_manifest_(NULL), 20 ld_manifest_(NULL),
20 obj_file_(NULL), 21 obj_file_(NULL),
21 nexe_file_(NULL), 22 nexe_file_(NULL),
22 coordinator_error_info_(NULL), 23 coordinator_error_info_(NULL),
23 resources_(NULL), 24 resources_(NULL),
24 plugin_(NULL) { 25 plugin_(NULL) {
25 NaClXMutexCtor(&subprocess_mu_); 26 NaClXMutexCtor(&subprocess_mu_);
27 NaClXMutexCtor(&cond_mu_);
28 NaClXCondVarCtor(&buffer_cond_);
29 }
30
31 void PnaclTranslateThread::RunTranslate(
32 const pp::CompletionCallback& finish_callback,
33 const Manifest* manifest,
34 const Manifest* ld_manifest,
35 TempFile* obj_file,
36 LocalTempFile* nexe_file,
37 ErrorInfo* error_info,
38 PnaclResources* resources,
39 Plugin* plugin) {
40 PLUGIN_PRINTF(("PnaclStreamingTranslateThread::RunTranslate)\n"));
41 manifest_ = manifest;
42 ld_manifest_ = ld_manifest;
43 obj_file_ = obj_file;
44 nexe_file_ = nexe_file;
45 coordinator_error_info_ = error_info;
46 resources_ = resources;
47 plugin_ = plugin;
48
49 // Invoke llc followed by ld off the main thread. This allows use of
50 // blocking RPCs that would otherwise block the JavaScript main thread.
51 report_translate_finished_ = finish_callback;
52 translate_thread_.reset(new NaClThread);
53 if (translate_thread_ == NULL) {
54 TranslateFailed("could not allocate thread struct.");
55 return;
56 }
57 const int32_t kArbitraryStackSize = 128 * 1024;
58 if (!NaClThreadCreateJoinable(translate_thread_.get(),
59 DoTranslateThread,
60 this,
61 kArbitraryStackSize)) {
62 TranslateFailed("could not create thread.");
63 translate_thread_.reset(NULL);
64 }
65 }
66
67 // Called from main thread to send bytes to the translator.
68 void PnaclTranslateThread::PutBytes(std::vector<char>* bytes,
69 int count) {
70 PLUGIN_PRINTF(("PutBytes, this %p bytes %p, size %d, count %d\n", this, bytes,
71 bytes ? bytes->size(): 0, count));
72 size_t buffer_size = 0;
73 // If we are done (error or not), Signal the translation thread to stop.
74 if (count <= PP_OK) {
75 NaClXMutexLock(&cond_mu_);
76 done_ = true;
77 NaClXCondVarSignal(&buffer_cond_);
78 NaClXMutexUnlock(&cond_mu_);
79 return;
80 }
81
82 CHECK(bytes != NULL);
83 // Ensure that the buffer we send to the translation thread is the right size
84 // (count can be < the buffer size). This can be done without the lock.
85 buffer_size = bytes->size();
86 bytes->resize(count);
87
88 NaClXMutexLock(&cond_mu_);
89
90 data_buffers_.push_back(std::vector<char>());
91 bytes->swap(data_buffers_.back()); // Avoid copying the buffer data.
92
93 NaClXCondVarSignal(&buffer_cond_);
94 NaClXMutexUnlock(&cond_mu_);
95
96 // Ensure the buffer we send back to the coordinator is the expected size
97 bytes->resize(buffer_size);
26 } 98 }
27 99
28 NaClSubprocess* PnaclTranslateThread::StartSubprocess( 100 NaClSubprocess* PnaclTranslateThread::StartSubprocess(
29 const nacl::string& url_for_nexe, 101 const nacl::string& url_for_nexe,
30 const Manifest* manifest, 102 const Manifest* manifest,
31 ErrorInfo* error_info) { 103 ErrorInfo* error_info) {
32 PLUGIN_PRINTF(("PnaclTranslateThread::StartSubprocess (url_for_nexe=%s)\n", 104 PLUGIN_PRINTF(("PnaclTranslateThread::StartSubprocess (url_for_nexe=%s)\n",
33 url_for_nexe.c_str())); 105 url_for_nexe.c_str()));
34 nacl::DescWrapper* wrapper = resources_->WrapperForUrl(url_for_nexe); 106 nacl::DescWrapper* wrapper = resources_->WrapperForUrl(url_for_nexe);
35 nacl::scoped_ptr<NaClSubprocess> subprocess( 107 nacl::scoped_ptr<NaClSubprocess> subprocess(
36 plugin_->LoadHelperNaClModule(wrapper, manifest, error_info)); 108 plugin_->LoadHelperNaClModule(wrapper, manifest, error_info));
37 if (subprocess.get() == NULL) { 109 if (subprocess.get() == NULL) {
38 PLUGIN_PRINTF(( 110 PLUGIN_PRINTF((
39 "PnaclTranslateThread::StartSubprocess: subprocess creation failed\n")); 111 "PnaclTranslateThread::StartSubprocess: subprocess creation failed\n"));
40 return NULL; 112 return NULL;
41 } 113 }
42 return subprocess.release(); 114 return subprocess.release();
43 } 115 }
44 116
45 void WINAPI PnaclTranslateThread::DoTranslateThread(void* arg) { 117 void WINAPI PnaclTranslateThread::DoTranslateThread(void* arg) {
46 PnaclTranslateThread* translator = 118 PnaclTranslateThread* translator =
47 reinterpret_cast<PnaclTranslateThread*>(arg); 119 reinterpret_cast<PnaclTranslateThread*>(arg);
48 translator->DoTranslate(); 120 translator->DoTranslate();
49 } 121 }
50 122
123 void PnaclTranslateThread::DoTranslate() {
124 ErrorInfo error_info;
125 nacl::scoped_ptr<NaClSubprocess> llc_subprocess(
126 StartSubprocess(PnaclUrls::GetLlcUrl(), manifest_, &error_info));
127 if (llc_subprocess == NULL) {
128 TranslateFailed("Compile process could not be created: " +
129 error_info.message());
130 return;
131 }
132 // Run LLC.
133 SrpcParams params;
134 nacl::DescWrapper* llc_out_file = obj_file_->get_wrapper();
135 PluginReverseInterface* llc_reverse =
136 llc_subprocess->service_runtime()->rev_interface();
137 llc_reverse->AddTempQuotaManagedFile(obj_file_->identifier());
138 RegisterReverseInterface(llc_reverse);
139
140 if (!llc_subprocess->InvokeSrpcMethod("StreamInit",
141 "h",
142 &params,
143 llc_out_file->desc())) {
144 // StreamInit returns an error message if the RPC fails.
145 TranslateFailed(nacl::string("Stream init failed: ") +
146 nacl::string(params.outs()[0]->arrays.str));
147 return;
148 }
149
150 PLUGIN_PRINTF(("PnaclCoordinator: StreamInit successful\n"));
151
152 // llc process is started.
153 while(!done_ || data_buffers_.size() > 0) {
154 NaClXMutexLock(&cond_mu_);
155 while(!done_ && data_buffers_.size() == 0) {
156 NaClXCondVarWait(&buffer_cond_, &cond_mu_);
157 }
158 PLUGIN_PRINTF(("PnaclTranslateThread awake, done %d, size %d\n",
159 done_, data_buffers_.size()));
160 if (data_buffers_.size() > 0) {
161 std::vector<char> data;
162 data.swap(data_buffers_.front());
163 data_buffers_.pop_front();
164 NaClXMutexUnlock(&cond_mu_);
165 PLUGIN_PRINTF(("StreamChunk\n"));
166 if (!llc_subprocess->InvokeSrpcMethod("StreamChunk",
167 "C",
168 &params,
169 &data[0],
170 data.size())) {
171 TranslateFailed("Compile stream chunk failed.");
172 return;
173 }
174 PLUGIN_PRINTF(("StreamChunk Successful\n"));
175 } else {
176 NaClXMutexUnlock(&cond_mu_);
177 }
178 if (SubprocessesShouldDie()) {
179 TranslateFailed("Stopped by coordinator.");
180 return;
181 }
182 }
183 PLUGIN_PRINTF(("PnaclTranslateThread done with chunks\n"));
184 // Finish llc.
185 if(!llc_subprocess->InvokeSrpcMethod("StreamEnd",
186 "",
187 &params)) {
188 PLUGIN_PRINTF(("PnaclTranslateThread StreamEnd failed\n"));
189 TranslateFailed(params.outs()[3]->arrays.str);
190 return;
191 }
192 // LLC returns values that are used to determine how linking is done.
193 int is_shared_library = (params.outs()[0]->u.ival != 0);
194 nacl::string soname = params.outs()[1]->arrays.str;
195 nacl::string lib_dependencies = params.outs()[2]->arrays.str;
196 PLUGIN_PRINTF(("PnaclCoordinator: compile (translator=%p) succeeded"
197 " is_shared_library=%d, soname='%s', lib_dependencies='%s')\n",
198 this, is_shared_library, soname.c_str(),
199 lib_dependencies.c_str()));
200
201 // Shut down the llc subprocess.
202 RegisterReverseInterface(NULL);
203 llc_subprocess.reset(NULL);
204 if (SubprocessesShouldDie()) {
205 TranslateFailed("stopped by coordinator.");
206 return;
207 }
208
209 if(!RunLdSubprocess(is_shared_library, soname, lib_dependencies)) {
210 return;
211 }
212 pp::Core* core = pp::Module::Get()->core();
213 core->CallOnMainThread(0, report_translate_finished_, PP_OK);
214 }
215
51 bool PnaclTranslateThread::RunLdSubprocess(int is_shared_library, 216 bool PnaclTranslateThread::RunLdSubprocess(int is_shared_library,
52 const nacl::string& soname, 217 const nacl::string& soname,
53 const nacl::string& lib_dependencies 218 const nacl::string& lib_dependencies
54 ) { 219 ) {
55 ErrorInfo error_info; 220 ErrorInfo error_info;
56 nacl::scoped_ptr<NaClSubprocess> ld_subprocess( 221 nacl::scoped_ptr<NaClSubprocess> ld_subprocess(
57 StartSubprocess(PnaclUrls::GetLdUrl(), ld_manifest_, &error_info)); 222 StartSubprocess(PnaclUrls::GetLdUrl(), ld_manifest_, &error_info));
58 if (ld_subprocess == NULL) { 223 if (ld_subprocess == NULL) {
59 TranslateFailed("Link process could not be created: " + 224 TranslateFailed("Link process could not be created: " +
60 error_info.message()); 225 error_info.message());
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 } 290 }
126 291
127 292
128 bool PnaclTranslateThread::SubprocessesShouldDie() { 293 bool PnaclTranslateThread::SubprocessesShouldDie() {
129 nacl::MutexLocker ml(&subprocess_mu_); 294 nacl::MutexLocker ml(&subprocess_mu_);
130 return subprocesses_should_die_; 295 return subprocesses_should_die_;
131 } 296 }
132 297
133 void PnaclTranslateThread::SetSubprocessesShouldDie() { 298 void PnaclTranslateThread::SetSubprocessesShouldDie() {
134 PLUGIN_PRINTF(("PnaclTranslateThread::SetSubprocessesShouldDie\n")); 299 PLUGIN_PRINTF(("PnaclTranslateThread::SetSubprocessesShouldDie\n"));
135 nacl::MutexLocker ml(&subprocess_mu_); 300 NaClXMutexLock(&subprocess_mu_);
136 subprocesses_should_die_ = true; 301 subprocesses_should_die_ = true;
137 if (current_rev_interface_) { 302 if (current_rev_interface_) {
138 current_rev_interface_->ShutDown(); 303 current_rev_interface_->ShutDown();
139 current_rev_interface_ = NULL; 304 current_rev_interface_ = NULL;
140 } 305 }
306 NaClXMutexUnlock(&subprocess_mu_);
307 nacl::MutexLocker ml(&cond_mu_);
308 done_ = true;
309 NaClXCondVarSignal(&buffer_cond_);
141 } 310 }
142 311
143 PnaclTranslateThread::~PnaclTranslateThread() { 312 PnaclTranslateThread::~PnaclTranslateThread() {
313 PLUGIN_PRINTF(("~PnaclTranslateThread (translate_thread=%p)\n", this));
314 SetSubprocessesShouldDie();
315 NaClThreadJoin(translate_thread_.get());
316 PLUGIN_PRINTF(("~PnaclTranslateThread joined\n"));
144 NaClMutexDtor(&subprocess_mu_); 317 NaClMutexDtor(&subprocess_mu_);
145 } 318 }
146 319
147 } // namespace plugin 320 } // namespace plugin
OLDNEW
« no previous file with comments | « ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698