Commit 231a96bb authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Fix deadlock in async compilation

This fixes a deadlock related to throttling: It can happen that all
background tasks detect that they should not produce more work because
of throttling (!CanAcceptWork()). Reducing the number of running
background tasks is done in a later step (OnBackgroundTaskStopped).
If the finisher task finishes all outstanding units between these two
calls, it will not schedule another background compilation task, but
all background compilation tasks will quit, hence compilation will
never finish.

Fixing this should allow us to reenable the 'wasm-finish-compilation'
test: https://crrev.com/c/999632

R=ahaas@chromium.org

Bug: chromium:824681
Change-Id: I967e4d6b2917d369dd49bb80ce4bef552d10b371
Reviewed-on: https://chromium-review.googlesource.com/1002174
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52483}
parent a29a6e8e
...@@ -122,7 +122,7 @@ class CompilationState { ...@@ -122,7 +122,7 @@ class CompilationState {
bool SetFinisherIsRunning(bool value); bool SetFinisherIsRunning(bool value);
void ScheduleFinisherTask(); void ScheduleFinisherTask();
bool CanAcceptWork() const; bool StopBackgroundCompilationTaskForThrottling();
void Abort(); void Abort();
...@@ -1288,17 +1288,16 @@ class BackgroundCompileTask : public CancelableTask { ...@@ -1288,17 +1288,16 @@ class BackgroundCompileTask : public CancelableTask {
void RunInternal() override { void RunInternal() override {
TRACE_COMPILE("(3b) Compiling...\n"); TRACE_COMPILE("(3b) Compiling...\n");
while (compilation_state_->CanAcceptWork()) { // The number of currently running background tasks is reduced either in
if (compilation_state_->failed()) break; // {StopBackgroundCompilationTaskForThrottling} or in
DisallowHandleAllocation no_handle; // {OnBackgroundTaskStopped}.
DisallowHeapAllocation no_allocation; while (!compilation_state_->StopBackgroundCompilationTaskForThrottling()) {
if (compilation_state_->failed() ||
if (!FetchAndExecuteCompilationUnit(compilation_state_)) { !FetchAndExecuteCompilationUnit(compilation_state_)) {
compilation_state_->OnBackgroundTaskStopped();
break; break;
} }
} }
compilation_state_->OnBackgroundTaskStopped();
} }
private: private:
...@@ -3197,9 +3196,12 @@ void CompilationState::ScheduleFinisherTask() { ...@@ -3197,9 +3196,12 @@ void CompilationState::ScheduleFinisherTask() {
base::make_unique<FinishCompileTask>(this, &foreground_task_manager_)); base::make_unique<FinishCompileTask>(this, &foreground_task_manager_));
} }
bool CompilationState::CanAcceptWork() const { bool CompilationState::StopBackgroundCompilationTaskForThrottling() {
base::LockGuard<base::Mutex> guard(&mutex_); base::LockGuard<base::Mutex> guard(&mutex_);
return executed_units_.CanAcceptWork(); DCHECK_LE(1, num_background_tasks_);
if (executed_units_.CanAcceptWork()) return false;
--num_background_tasks_;
return true;
} }
void CompilationState::Abort() { void CompilationState::Abort() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment