Commit 8e470e32 authored by Sam Maier's avatar Sam Maier Committed by Commit Bot

Rerouting all Java tasks through TaskRunner API

Pre-native Java tasks are now having their priority set when started.
Also switches dynamicmodule's ModuleLoader to use the TaskTrait's
priority setting instead of manually setting the thread priority.

Bug: 863457
Change-Id: Iee601ca1e18e2637f8e930c6d212c8115e682fc3
Reviewed-on: https://chromium-review.googlesource.com/c/1407374Reviewed-by: default avatarSami Kyöstilä <skyostil@chromium.org>
Reviewed-by: default avatarYaron Friedman <yfriedman@chromium.org>
Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Reviewed-by: default avatarBenoit L <lizeb@chromium.org>
Commit-Queue: Sam Maier <smaier@chromium.org>
Cr-Commit-Position: refs/heads/master@{#626095}
parent 0a81ee34
......@@ -5,7 +5,6 @@
package org.chromium.base.task;
import android.os.Binder;
import android.os.Process;
import android.support.annotation.IntDef;
import android.support.annotation.MainThread;
import android.support.annotation.WorkerThread;
......@@ -34,10 +33,14 @@ import java.util.concurrent.atomic.AtomicBoolean;
public abstract class AsyncTask<Result> {
private static final String TAG = "AsyncTask";
private static TaskTraits sLowPriorityTraits =
new TaskTraits().setTaskPriority(TaskPriority.LOWEST).setMayBlock(true);
/**
* An {@link Executor} that can be used to execute tasks in parallel.
* We use the lowest task priority, and mayBlock = true since any user of this could block.
*/
public static final Executor THREAD_POOL_EXECUTOR = new ChromeThreadPoolExecutor();
public static final Executor THREAD_POOL_EXECUTOR =
(Runnable r) -> PostTask.postTask(sLowPriorityTraits, r);
/**
* An {@link Executor} that executes tasks one at a time in serial
......@@ -100,7 +103,6 @@ public abstract class AsyncTask<Result> {
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
result = doInBackground();
Binder.flushPendingCommands();
} catch (Throwable tr) {
......@@ -353,6 +355,20 @@ public abstract class AsyncTask<Result> {
return this;
}
/**
* Executes an AsyncTask with the given task traits. Provides no guarantees about sequencing or
* which thread it runs on.
*
* @param taskTraits traits which describe this AsyncTask.
* @return This instance of AsyncTask.
*/
@MainThread
public final AsyncTask<Result> executeWithTaskTraits(TaskTraits taskTraits) {
executionPreamble();
PostTask.postTask(taskTraits, mFuture);
return this;
}
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
......
......@@ -6,6 +6,8 @@ package org.chromium.base.task;
import static java.util.concurrent.TimeUnit.SECONDS;
import android.os.Process;
import org.chromium.base.BuildConfig;
import org.chromium.base.VisibleForTesting;
......@@ -34,7 +36,11 @@ class ChromeThreadPoolExecutor extends ThreadPoolExecutor {
private final AtomicInteger mCount = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "CrAsyncTask #" + mCount.getAndIncrement());
Thread t = new Thread(() -> {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
r.run();
}, "CrAsyncTask #" + mCount.getAndIncrement());
return t;
}
};
......@@ -109,9 +115,9 @@ class ChromeThreadPoolExecutor extends ThreadPoolExecutor {
}
@Override
public void execute(Runnable command) {
public void execute(Runnable r) {
try {
super.execute(command);
super.execute(r);
} catch (RejectedExecutionException e) {
Map<String, Integer> counts = getNumberOfClassNameOccurrencesInQueue();
......
......@@ -4,6 +4,7 @@
package org.chromium.base.task;
import android.os.Process;
import android.support.annotation.Nullable;
import android.util.Pair;
......@@ -21,7 +22,6 @@ import java.util.List;
*/
@JNINamespace("base")
public class TaskRunnerImpl implements TaskRunner {
@Nullable
private final TaskTraits mTaskTraits;
private final String mTraceEvent;
private final @TaskRunnerType int mTaskRunnerType;
......@@ -30,6 +30,8 @@ public class TaskRunnerImpl implements TaskRunner {
protected final Runnable mRunPreNativeTaskClosure = this::runPreNativeTask;
private boolean mIsDestroying;
private final GcStateAssert mGcStateAssert = GcStateAssert.create(this, true);
private static final ChromeThreadPoolExecutor THREAD_POOL_EXECUTOR =
new ChromeThreadPoolExecutor();
@Nullable
protected LinkedList<Runnable> mPreNativeTasks = new LinkedList<>();
......@@ -99,7 +101,7 @@ public class TaskRunnerImpl implements TaskRunner {
* time.
*/
protected void schedulePreNativeTask() {
AsyncTask.THREAD_POOL_EXECUTOR.execute(mRunPreNativeTaskClosure);
THREAD_POOL_EXECUTOR.execute(mRunPreNativeTaskClosure);
}
/**
......@@ -112,6 +114,18 @@ public class TaskRunnerImpl implements TaskRunner {
if (mPreNativeTasks == null) return;
task = mPreNativeTasks.poll();
}
switch (mTaskTraits.mPriority) {
case TaskPriority.USER_VISIBLE:
Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
break;
case TaskPriority.HIGHEST:
Process.setThreadPriority(Process.THREAD_PRIORITY_MORE_FAVORABLE);
break;
default:
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
break;
}
task.run();
}
}
......
......@@ -12,7 +12,6 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Process;
import android.support.annotation.Nullable;
import dalvik.system.DexClassLoader;
......@@ -24,6 +23,8 @@ import org.chromium.base.Log;
import org.chromium.base.ObserverList;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.task.AsyncTask;
import org.chromium.base.task.TaskPriority;
import org.chromium.base.task.TaskTraits;
import org.chromium.chrome.browser.ChromeApplication;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.customtabs.dynamicmodule.ModuleMetrics.DestructionReason;
......@@ -154,7 +155,10 @@ public class ModuleLoader {
ModuleMetrics.registerLifecycleState(ModuleMetrics.LifecycleState.NOT_LOADED);
mIsModuleLoading = true;
new LoadClassTask(moduleContext).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new LoadClassTask(moduleContext)
.executeWithTaskTraits(new TaskTraits()
.setTaskPriority(TaskPriority.USER_VISIBLE)
.setMayBlock(true));
}
/**
......@@ -326,16 +330,7 @@ public class ModuleLoader {
@Override
@Nullable
protected Class<?> doInBackground() {
int oldPriority = Process.getThreadPriority(0);
try {
// We don't want to block the UI thread, but we don't want to be really slow either.
// The AsyncTask class sets the thread priority quite low
// (THREAD_PRIORITY_BACKGROUND) and does not distinguish between user-visible
// user-invisible tasks.
// TODO(crbug.com/863457): Replace this with something like a task trait that
// influences priority once we have a task scheduler in Java.
Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
boolean loadFromDex = updateModuleDexInDiskIfNeeded();
long entryPointLoadClassStartTime = ModuleMetrics.now();
Class<?> clazz =
......@@ -349,8 +344,6 @@ public class ModuleLoader {
Log.e(TAG, "Could not copy dex to local storage", e);
ModuleMetrics.recordLoadResult(
ModuleMetrics.LoadResult.FAILED_TO_COPY_DEX_EXCEPTION);
} finally {
Process.setThreadPriority(oldPriority);
}
return null;
}
......
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