From b8dd2652982f165a6f206b16b189baf78602ffcf Mon Sep 17 00:00:00 2001 From: Tim Murray Date: Fri, 23 Jun 2023 16:27:43 -0700 Subject: SharedPreferences: replace per-load threads with single thread Switch to a shared executor instead of explicit threads for SharedPreferences loads in order to reduce mmap_sem contention from thread creation spam. Test: atest android.content.cts.SharedPreferencesTest Bug: 289006197 Change-Id: Ieed7bdaa3f08c3fe9121b157d8bdb29b013f4b83 --- core/java/android/app/SharedPreferencesImpl.java | 28 +++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java index 1ebf56550e03..a87187b8affb 100644 --- a/core/java/android/app/SharedPreferencesImpl.java +++ b/core/java/android/app/SharedPreferencesImpl.java @@ -55,6 +55,11 @@ import java.util.Map; import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; final class SharedPreferencesImpl implements SharedPreferences { private static final String TAG = "SharedPreferencesImpl"; @@ -119,6 +124,10 @@ final class SharedPreferencesImpl implements SharedPreferences { private final ExponentiallyBucketedHistogram mSyncTimes = new ExponentiallyBucketedHistogram(16); private int mNumSync = 0; + private static final ThreadPoolExecutor sLoadExecutor = new ThreadPoolExecutor(0, 1, 10L, + TimeUnit.SECONDS, new LinkedBlockingQueue(), + new SharedPreferencesThreadFactory()); + @UnsupportedAppUsage SharedPreferencesImpl(File file, int mode) { mFile = file; @@ -135,11 +144,10 @@ final class SharedPreferencesImpl implements SharedPreferences { synchronized (mLock) { mLoaded = false; } - new Thread("SharedPreferencesImpl-load") { - public void run() { - loadFromDisk(); - } - }.start(); + + sLoadExecutor.execute(() -> { + loadFromDisk(); + }); } private void loadFromDisk() { @@ -874,4 +882,14 @@ final class SharedPreferencesImpl implements SharedPreferences { } mcr.setDiskWriteResult(false, false); } + + + private static final class SharedPreferencesThreadFactory implements ThreadFactory { + @Override + public Thread newThread(Runnable runnable) { + Thread thread = Executors.defaultThreadFactory().newThread(runnable); + thread.setName("SharedPreferences"); + return thread; + } + } } -- cgit v1.2.3-59-g8ed1b