summaryrefslogtreecommitdiff
path: root/adservices/service-core/java/com/android/adservices/concurrency/AdServicesExecutors.java
diff options
context:
space:
mode:
Diffstat (limited to 'adservices/service-core/java/com/android/adservices/concurrency/AdServicesExecutors.java')
-rw-r--r--adservices/service-core/java/com/android/adservices/concurrency/AdServicesExecutors.java62
1 files changed, 55 insertions, 7 deletions
diff --git a/adservices/service-core/java/com/android/adservices/concurrency/AdServicesExecutors.java b/adservices/service-core/java/com/android/adservices/concurrency/AdServicesExecutors.java
index 379d181ed2..0795441e62 100644
--- a/adservices/service-core/java/com/android/adservices/concurrency/AdServicesExecutors.java
+++ b/adservices/service-core/java/com/android/adservices/concurrency/AdServicesExecutors.java
@@ -17,14 +17,18 @@
package com.android.adservices.concurrency;
import android.annotation.NonNull;
+import android.annotation.SuppressLint;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
/**
* ALl executors of the PP API module.
@@ -34,14 +38,35 @@ import java.util.concurrent.TimeUnit;
// TODO(b/224987182): set appropriate parameters (priority, size, etc..) for the shared thread pools
// after doing detailed analysis. Ideally the parameters should be backed by PH flags.
public final class AdServicesExecutors {
- // We set the minimal number of threads for background executor to 4 and lightweight executor to
- // 2 since Runtime.getRuntime().availableProcessors() may return 1 or 2 for low-end devices.
- // This may cause deadlock for starvation in those low-end devices.
+ // We set the minimal number of threads for background executor to 4 and lightweight & scheduled
+ // executors to 2 since Runtime.getRuntime().availableProcessors() may return 1 or 2 for
+ // low-end devices. This may cause deadlock for starvation in those low-end devices.
private static final int MIN_BACKGROUND_EXECUTOR_THREADS = 4;
private static final int MIN_LIGHTWEIGHT_EXECUTOR_THREADS = 2;
+ private static final int MAX_SCHEDULED_EXECUTOR_THREADS = 4;
+
+ private static final String LIGHTWEIGHT_NAME = "lightweight";
+ private static final String BACKGROUND_NAME = "background";
+ private static final String SCHEDULED_NAME = "scheduled";
+ private static final String BLOCKING_NAME = "blocking";
+
+ private static ThreadFactory getFactory(final String threadPrefix) {
+ return new ThreadFactory() {
+ private final AtomicLong mThreadCount = new AtomicLong(0L);
+
+ @SuppressLint("DefaultLocale")
+ @Override
+ public Thread newThread(Runnable runnable) {
+ Thread thread = Executors.defaultThreadFactory().newThread(runnable);
+ thread.setName(
+ String.format("%s-%d", threadPrefix, mThreadCount.incrementAndGet()));
+ return thread;
+ }
+ };
+ }
private static final ListeningExecutorService sLightWeightExecutor =
- // Always use at least two threads, so that clients can't depend on light weight
+ // Always use at least two threads, so that clients can't depend on light-weight
// executor tasks executing sequentially
MoreExecutors.listeningDecorator(
new ThreadPoolExecutor(
@@ -54,7 +79,8 @@ public final class AdServicesExecutors {
Runtime.getRuntime().availableProcessors() - 2),
/* keepAliveTime = */ 60L,
TimeUnit.SECONDS,
- new LinkedBlockingQueue<>()));
+ new LinkedBlockingQueue<>(),
+ getFactory(LIGHTWEIGHT_NAME)));
/**
* Functions that don't do direct I/O and that are fast (under ten milliseconds or thereabouts)
@@ -78,7 +104,8 @@ public final class AdServicesExecutors {
Runtime.getRuntime().availableProcessors()),
/* keepAliveTime = */ 60L,
TimeUnit.SECONDS,
- new LinkedBlockingQueue<>()));
+ new LinkedBlockingQueue<>(),
+ getFactory(BACKGROUND_NAME)));
/**
* Functions that directly execute disk I/O, or that are CPU bound and long-running (over ten
@@ -93,8 +120,29 @@ public final class AdServicesExecutors {
return sBackgroundExecutor;
}
+ private static final ScheduledThreadPoolExecutor sScheduler =
+ new ScheduledThreadPoolExecutor(
+ /* corePoolSize = */ Math.min(
+ MAX_SCHEDULED_EXECUTOR_THREADS,
+ Runtime.getRuntime().availableProcessors()),
+ getFactory(SCHEDULED_NAME));
+
+ /**
+ * Functions that require to be run with a delay, or have timed executions should run on this
+ * Executor
+ *
+ * <p>Example includes having timeouts on Futures
+ *
+ * @return
+ */
+ @NonNull
+ public static ScheduledThreadPoolExecutor getScheduler() {
+ return sScheduler;
+ }
+
private static final ListeningExecutorService sBlockingExecutor =
- MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
+ MoreExecutors.listeningDecorator(
+ Executors.newCachedThreadPool(getFactory(BLOCKING_NAME)));
/**
* Functions that directly execute network I/O, or that block their thread awaiting the progress