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 @@ ...@@ -5,7 +5,6 @@
package org.chromium.base.task; package org.chromium.base.task;
import android.os.Binder; import android.os.Binder;
import android.os.Process;
import android.support.annotation.IntDef; import android.support.annotation.IntDef;
import android.support.annotation.MainThread; import android.support.annotation.MainThread;
import android.support.annotation.WorkerThread; import android.support.annotation.WorkerThread;
...@@ -34,10 +33,14 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -34,10 +33,14 @@ import java.util.concurrent.atomic.AtomicBoolean;
public abstract class AsyncTask<Result> { public abstract class AsyncTask<Result> {
private static final String TAG = "AsyncTask"; 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. * 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 * An {@link Executor} that executes tasks one at a time in serial
...@@ -100,7 +103,6 @@ public abstract class AsyncTask<Result> { ...@@ -100,7 +103,6 @@ public abstract class AsyncTask<Result> {
mTaskInvoked.set(true); mTaskInvoked.set(true);
Result result = null; Result result = null;
try { try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
result = doInBackground(); result = doInBackground();
Binder.flushPendingCommands(); Binder.flushPendingCommands();
} catch (Throwable tr) { } catch (Throwable tr) {
...@@ -353,6 +355,20 @@ public abstract class AsyncTask<Result> { ...@@ -353,6 +355,20 @@ public abstract class AsyncTask<Result> {
return this; 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) { private void finish(Result result) {
if (isCancelled()) { if (isCancelled()) {
onCancelled(result); onCancelled(result);
......
...@@ -6,6 +6,8 @@ package org.chromium.base.task; ...@@ -6,6 +6,8 @@ package org.chromium.base.task;
import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.concurrent.TimeUnit.SECONDS;
import android.os.Process;
import org.chromium.base.BuildConfig; import org.chromium.base.BuildConfig;
import org.chromium.base.VisibleForTesting; import org.chromium.base.VisibleForTesting;
...@@ -34,7 +36,11 @@ class ChromeThreadPoolExecutor extends ThreadPoolExecutor { ...@@ -34,7 +36,11 @@ class ChromeThreadPoolExecutor extends ThreadPoolExecutor {
private final AtomicInteger mCount = new AtomicInteger(1); private final AtomicInteger mCount = new AtomicInteger(1);
@Override @Override
public Thread newThread(Runnable r) { 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 { ...@@ -109,9 +115,9 @@ class ChromeThreadPoolExecutor extends ThreadPoolExecutor {
} }
@Override @Override
public void execute(Runnable command) { public void execute(Runnable r) {
try { try {
super.execute(command); super.execute(r);
} catch (RejectedExecutionException e) { } catch (RejectedExecutionException e) {
Map<String, Integer> counts = getNumberOfClassNameOccurrencesInQueue(); Map<String, Integer> counts = getNumberOfClassNameOccurrencesInQueue();
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package org.chromium.base.task; package org.chromium.base.task;
import android.os.Process;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.Pair; import android.util.Pair;
...@@ -21,7 +22,6 @@ import java.util.List; ...@@ -21,7 +22,6 @@ import java.util.List;
*/ */
@JNINamespace("base") @JNINamespace("base")
public class TaskRunnerImpl implements TaskRunner { public class TaskRunnerImpl implements TaskRunner {
@Nullable
private final TaskTraits mTaskTraits; private final TaskTraits mTaskTraits;
private final String mTraceEvent; private final String mTraceEvent;
private final @TaskRunnerType int mTaskRunnerType; private final @TaskRunnerType int mTaskRunnerType;
...@@ -30,6 +30,8 @@ public class TaskRunnerImpl implements TaskRunner { ...@@ -30,6 +30,8 @@ public class TaskRunnerImpl implements TaskRunner {
protected final Runnable mRunPreNativeTaskClosure = this::runPreNativeTask; protected final Runnable mRunPreNativeTaskClosure = this::runPreNativeTask;
private boolean mIsDestroying; private boolean mIsDestroying;
private final GcStateAssert mGcStateAssert = GcStateAssert.create(this, true); private final GcStateAssert mGcStateAssert = GcStateAssert.create(this, true);
private static final ChromeThreadPoolExecutor THREAD_POOL_EXECUTOR =
new ChromeThreadPoolExecutor();
@Nullable @Nullable
protected LinkedList<Runnable> mPreNativeTasks = new LinkedList<>(); protected LinkedList<Runnable> mPreNativeTasks = new LinkedList<>();
...@@ -99,7 +101,7 @@ public class TaskRunnerImpl implements TaskRunner { ...@@ -99,7 +101,7 @@ public class TaskRunnerImpl implements TaskRunner {
* time. * time.
*/ */
protected void schedulePreNativeTask() { protected void schedulePreNativeTask() {
AsyncTask.THREAD_POOL_EXECUTOR.execute(mRunPreNativeTaskClosure); THREAD_POOL_EXECUTOR.execute(mRunPreNativeTaskClosure);
} }
/** /**
...@@ -112,6 +114,18 @@ public class TaskRunnerImpl implements TaskRunner { ...@@ -112,6 +114,18 @@ public class TaskRunnerImpl implements TaskRunner {
if (mPreNativeTasks == null) return; if (mPreNativeTasks == null) return;
task = mPreNativeTasks.poll(); 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(); task.run();
} }
} }
......
...@@ -12,7 +12,6 @@ import android.content.pm.PackageInfo; ...@@ -12,7 +12,6 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.os.Process;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import dalvik.system.DexClassLoader; import dalvik.system.DexClassLoader;
...@@ -24,6 +23,8 @@ import org.chromium.base.Log; ...@@ -24,6 +23,8 @@ import org.chromium.base.Log;
import org.chromium.base.ObserverList; import org.chromium.base.ObserverList;
import org.chromium.base.VisibleForTesting; import org.chromium.base.VisibleForTesting;
import org.chromium.base.task.AsyncTask; 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.ChromeApplication;
import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.customtabs.dynamicmodule.ModuleMetrics.DestructionReason; import org.chromium.chrome.browser.customtabs.dynamicmodule.ModuleMetrics.DestructionReason;
...@@ -154,7 +155,10 @@ public class ModuleLoader { ...@@ -154,7 +155,10 @@ public class ModuleLoader {
ModuleMetrics.registerLifecycleState(ModuleMetrics.LifecycleState.NOT_LOADED); ModuleMetrics.registerLifecycleState(ModuleMetrics.LifecycleState.NOT_LOADED);
mIsModuleLoading = true; 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 { ...@@ -326,16 +330,7 @@ public class ModuleLoader {
@Override @Override
@Nullable @Nullable
protected Class<?> doInBackground() { protected Class<?> doInBackground() {
int oldPriority = Process.getThreadPriority(0);
try { 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(); boolean loadFromDex = updateModuleDexInDiskIfNeeded();
long entryPointLoadClassStartTime = ModuleMetrics.now(); long entryPointLoadClassStartTime = ModuleMetrics.now();
Class<?> clazz = Class<?> clazz =
...@@ -349,8 +344,6 @@ public class ModuleLoader { ...@@ -349,8 +344,6 @@ public class ModuleLoader {
Log.e(TAG, "Could not copy dex to local storage", e); Log.e(TAG, "Could not copy dex to local storage", e);
ModuleMetrics.recordLoadResult( ModuleMetrics.recordLoadResult(
ModuleMetrics.LoadResult.FAILED_TO_COPY_DEX_EXCEPTION); ModuleMetrics.LoadResult.FAILED_TO_COPY_DEX_EXCEPTION);
} finally {
Process.setThreadPriority(oldPriority);
} }
return null; 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